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

问题描述 投票:0回答:2

我想用CEF4构建一个测试应用程序。我已经成功地在C ++ Builder中安装了CEF4Delphi(github.com/salvadordf/CEF4Delphi)组件。我想在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 =?的成员函数。

c++ delphi c++builder chromium-embedded cef4delphi
2个回答
2
投票

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事件需要指向非静态类方法的指针。
  • 如果您使用的是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()才能将其用作匿名事件处理程序。要做到这一点,根据您使用的是经典的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(); };

3
投票

成员函数必须符合他们所在的类。

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

© www.soinside.com 2019 - 2024. All rights reserved.