设置成员 GlobalCEFApp->OnWebKitInitialized 函数地址 C++ Builder

Set a member GlobalCEFApp->OnWebKitInitialized with function address C++ Builder

我想用 CEF4.I 构建一个测试应用程序,已成功将 CEF4Delphi (github.com/salvadordf/CEF4Delphi) 组件安装到 C++ Builder。我想在 C++ Builder 中构建 JSExtension delphi 演示项目。

我正在尝试为成员设置函数,但每次都出现相同的错误:

[bcc32 错误]Unit1.cpp(35): E2235 成员函数必须被调用或者其地址被占用

我都试过了:

//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; 

如何正确地做到这一点?

我在 C++ Builder 中使用 CEF4Delphi (github.com/salvadordf/CEF4Delphi) 组件。在 delphi JSExtension 演示项目上它运行良好,但我无法构建同一演示的 C++ 版本。 C++使用了delphi接口,不知道如何正确使用。我需要将我的函数分配给 GlobalCEFApp->OnWebKitInitialized = 的成员函数?

成员函数必须用它们所在的 class 限定。

所以你需要使用&TheClassOfTheFunction::GlobalCEFApp_OnWebKitInitialized

TCefApplication::OnWebKitInitialized事件声明为使用TOnWebKitInitializedEvent类型,在uCEFInterfaces.pas单元中声明为:

TOnWebKitInitializedEvent = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure() {$IFNDEF DELPHI12_UP}of object{$ENDIF};

CEF 在 Delphi/C++Builder 2009 及更高版本中定义 DELPHI12_UP

您没有说明您使用的是哪个版本的 C++Builder。

  • 如果您使用的是 C++Builder 2007 或更早版本,OnWebKitInitialized 事件需要一个指向 非静态 class 方法的指针.

  • 如果您使用的是 C++Builder 2009+,OnWebKitInitialized 事件需要一个 anonymous method

由于您提到您尝试使用 _di_TOnWebKitInitializedEvent,它仅在 TOnWebKitInitializedEvent 是匿名方法类型时才存在,我必须假设您使用的是 C++Builder 2009+。

在 C++ 中,Delphi 风格的匿名方法需要特殊处理,Embarcadero 对此进行了记录:

How to Handle Delphi Anonymous Methods in C++

您需要包装 GlobalCEFApp_OnWebKitInitialized() 以便将其用作匿名事件处理程序。为此,根据您使用的是 classic Borland Win32/OSX 编译器还是较新的 Clang-based compilers 之一,您有几个选择。

  • 经典:你必须写一个实现TOnWebKitInitializedEvent接口的仿函数:

    class TWebKitInitRef : public TCppInterfacedObject<TOnWebKitInitializedEvent>
    {
    public:
        INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
        void __fastcall Invoke() { GlobalCEFApp_OnWebKitInitialized(); }
    };
    
    GlobalCEFApp->OnWebKitInitialized = _di_TOnWebKitInitializedEvent(new TWebKitInitRef());
    
  • Clang:您可以使用 C++ lambda:

    GlobalCEFApp->OnWebKitInitialized = [](){ GlobalCEFApp_OnWebKitInitialized(); };