I want to build a test application with CEF4.I have installed CEF4Delphi (github.com/salvadordf/CEF4Delphi) component to C++ Builder successfuly. And I want to build the JSExtension delphi demo project in C++ Builder.
I'm trying to set a function to a member, but each time a get same error:
[bcc32 Error] Unit1.cpp(35): E2235 Member function must be called or its address taken
I tried all of them:
//This is my function, just a global function
void GlobalCEFApp_OnWebKitInitialized();
//For GlobalCEFApp object I want to assign my function to a member function OnWebKitInitialized of that object
GlobalCEFApp = new TCefApplication();
// I tried this:
GlobalCEFApp->OnWebKitInitialized = GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp->OnWebKitInitialized = &GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp->OnWebKitInitialized = (_di_TOnWebKitInitializedEvent*)GlobalCEFApp_OnWebKitInitialized;
GlobalCEFApp->OnWebKitInitialized = reinterpret_cast<TOnWebKitInitializedEvent &>(GlobalCEFApp_OnWebKitInitialized);
//But only this compiled, however it gives access violation at runtime
GlobalCEFApp->OnWebKitInitialized = ( _di_TOnWebKitInitializedEvent &)GlobalCEFApp_OnWebKitInitialized;
How to do that correctly ?
I use CEF4Delphi (github.com/salvadordf/CEF4Delphi) component in C++ Builder. On delphi JSExtension demo project it is working good, but I cannot build the C++ version of the same demo. C++ uses delphi interfaces, and I don't know how to use it correctly. I need to assign my function to the member function for GlobalCEFApp->OnWebKitInitialized = ?
The TCefApplication::OnWebKitInitialized
event is declared as using the TOnWebKitInitializedEvent
type, which is declared in the uCEFInterfaces.pas
unit as:
TOnWebKitInitializedEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure() {$IFNDEF DELPHI12_UP}of object{$ENDIF};
CEF defines DELPHI12_UP
in Delphi/C++Builder 2009 and later.
You did not say which version of C++Builder you are using.
If you are using C++Builder 2007 or earlier, the OnWebKitInitialized
event expects a pointer to a non-static class method.
If you are using C++Builder 2009+, the OnWebKitInitialized
event expects an anonymous method instead.
Since you mention that you tried using _di_TOnWebKitInitializedEvent
, which only exists if TOnWebKitInitializedEvent
is an anonymous method type, I have to assume you are using C++Builder 2009+.
In C++, Delphi-style anonymous methods require special handling, which Embarcadero has documented:
How to Handle Delphi Anonymous Methods in C++
You need to wrap GlobalCEFApp_OnWebKitInitialized()
in order to use it as an anonymous event handler. To do that, you have a couple of choices depending on whether you are using the classic Borland Win32/OSX compiler or one of the newer Clang-based compilers.
Classic: You must write a functor that implements the TOnWebKitInitializedEvent
interface:
class TWebKitInitRef : public TCppInterfacedObject<TOnWebKitInitializedEvent>
{
public:
INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
void __fastcall Invoke() { GlobalCEFApp_OnWebKitInitialized(); }
};
GlobalCEFApp->OnWebKitInitialized = _di_TOnWebKitInitializedEvent(new TWebKitInitRef());
Clang: You can use a C++ lambda:
GlobalCEFApp->OnWebKitInitialized = [](){ GlobalCEFApp_OnWebKitInitialized(); };