Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
lambda functions with classic 32 bit Borland compiler ?
#1
Hi,

the Intraweb Application Wizard creates by default a C++ project for the classic 32 bit Borland compiler,
but now the default compiler for Embarcadero RAD Studio 10.3.2 32 AND 64 bit  is CLANG.

The classic 32 bit Borland compiler does not provide C++11 lamda function support,
therefore gsession functions like Excecute() and LookUp() probably can not be used with this compiler.

Turning off the classic 32 bit compiler creates an error message in IWInit.hpp

namespace Iwinit
{
  extern Iwapplication::TIWApplication* __thread WebApplication;
}

Regards
JuergenS
Reply
#2
Is it safe to just change our wizard to use the classic compiler? Or is this a global setting and not per project?

This seems like quite hefty change CLANG is imposing on existing BCB code bases.
Reply
#3
(08-18-2019, 05:51 PM)JuergenS Wrote: Hi,

the Intraweb Application Wizard creates by default a C++ project for the classic 32 bit Borland compiler,
but now the default compiler for Embarcadero RAD Studio 10.3.2 32 AND 64 bit  is CLANG.

The classic 32 bit Borland compiler does not provide C++11 lamda function support,
therefore gsession functions like Excecute() and LookUp() probably can not be used with this compiler.

Turning off the classic 32 bit compiler creates an error message in IWInit.hpp

namespace Iwinit
{
  extern Iwapplication::TIWApplication* __thread WebApplication;
}

Regards
JuergenS

You don't need to use lambdas (anonymous functions). This is *another* option.

You can pass a method pointer as you do with normal callbacks and it should work exactly the same. Have you tried?
Reply
#4
Hi Alexandre,

No, I did not try it, because I now believe that I can no longer use these TIWSessions methods for my purposes.

My application has an automatic maintenance mode.
Before entering the maintenance mode, the application iterates over all sessions and issues localized information to each user.
After a defined waiting time, the application iterates again over all sessions and terminates them.
The problem is that within these TIWSessions methods I can neither create the localized information nor terminate a session.
I'll probably have to implement another solution that works equally well with both compilers.

Basically, the CLANG compiler is probably the future standard for RAD Studio for 32/64 bit.
During development, I still use the classic Borland compiler, because compilation time is simply dramatically faster.
Switching to the CLANG compiler is possible by simply modifying a project option.
However, I still have this problem in IWInit.hpp found.

Regards
JuergenS
Reply
#5
(08-19-2019, 04:41 PM)JuergenS Wrote: No, I did not try it, because I now believe that I can no longer use these TIWSessions methods for my purposes.

My application has an automatic maintenance mode.
Before entering the maintenance mode, the application iterates over all sessions and issues localized information to each user.
After a defined waiting time, the application iterates again over all sessions and terminates them.
The problem is that within these TIWSessions methods I can neither create the localized information nor terminate a session.
I'll probably have to implement another solution that works equally well with both compilers.

I don't terminate sessions directly from the list, but you can set a flag/variable in the session's UserSession that could tell the session to warn and/or shut itself down if that might be an option for you.

Dan
Reply
#6
You can switch to CLANG for 64 bits.

Can you show me (or send it to my email) the code you are trying to use with new IW 15.1?

> The problem is that within these TIWSessions methods I can neither create the localized information nor terminate a session.

Can you elaborate this a little more? From IW perspective, there is no such limitation.

I'm 100% sure that method pointers will work just like it does in several parts of VCL which uses them (and are used by any C++ applications, both CLANG and classic compiler)
Reply
#7
Hi Alexandre,

Thank you for your response.
I also think that methods pointers would work but meanwhile I have implemented another solution that works with all compilers.

Regards
Juergen
Reply
#8
As we are still debating what to do moving forward, would you mind sharing those solutions?
Reply
#9
Hi,

my solution is specific to my current application and therefore can not be generalized like this.
An already existing list of logged in users will be used, which will also have access to
the user session data module (TIWUserSession) of a logged in user.

The class TIWSessions certainly contains all the methods to work with all active sessions.
Unfortunately, the functions of this important class are not well documented.
Removing Lock / Unlock has contributed to the stability.
For functions with anonymous functions as function parameters (Execute, LookUp)
arise in my view the following problems:

- C ++ interface definitions for lambda functions are generated for the anonymous functions,
  which can not be processed by the current classic 32-bit C ++ compiler.
- Within the scope of the defined lambda functions, only the session object can be accessed.
  Access to global data, functions or objects of the application is not possible.
  Maybe an additional interface parameter for accessing global application data would be useful.

Regards
Juergen
Reply
#10
Sample anonymous function usage with C++ classic compiler without lambda functions:


//---------------------------------------------------------------------------
From 'How to Handle Delphi Anonymous Methods in C++' RAD Studio help.
This needs to be included once so the function pointers can be wrapped.
//---------------------------------------------------------------------------
enum _DummyType{};
template <typename INTF, // Interface with Invoke
          typename F,    // Functor type
          typename R,    // Return type
          typename P1 = _DummyType,  // Param #1
          typename P2 = _DummyType,  // Param #2
          typename P3 = _DummyType,  // Param #3
          typename P4 = _DummyType,  // Param #4
          typename P5 = _DummyType>  // Param #5
class TMethodRef : public TCppInterfacedObject<INTF>
{
private:
  F callback;
public:
  TMethodRef(F _callback) : callback(_callback) {}
  INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
  R __fastcall Invoke(P1 p1) {
    return callback(p1);
  }
  R __fastcall Invoke(P1 p1, P2 p2) {
    return callback(p1, p2);
  }
  R __fastcall Invoke(P1 p1, P2 p2, P3 p3) {
    return callback(p1, p2, p3);
  }
  R __fastcall Invoke(P1 p1, P2 p2, P3 p3, P4 p4) {
    return callback(p1, p2, p3, p4);
  }
  R __fastcall Invoke(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    return callback(p1, p2, p3, p4, p5);
  }
};


//Sample TSessionProc callback
//---------------------------------------------------------------------------
void LookUpProc(System::TObject* obj)
{
  TIWApplication *ASession =  (TIWApplication *)obj;
  UserSession()->tmpStr = ASession->IP+","+ASession->LastAccess.FormatString("yyyy-mm-dd hh:nnConfuseds");
}


// Sample callback usage
//---------------------------------------------------------------------------
void __fastcall TMJForm::btnRefreshAsyncClick(TObject *Sender, TStringList *EventParams)
{
  auto_ptr<TStringList> sl(new TStringList), sl2(new TStringList);
  
  gSessions->GetList(sl.get());
  for(int i=0;i<sl->Count;i++) {
    gSessions->LookUp(sl->Strings[i],new TMethodRef<Iwlfsessionlist::TSessionProc,void (*)(System::TObject*),void,System::TObject* >(LookUpProc));
    sl2->DelimitedText = UserSession()->tmpStr;
    ...
  }
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)