Установите член GlobalCEFApp-> OnWebKitInitialized с адресом функции C ++ Builder - PullRequest
0 голосов
/ 22 марта 2019

Я хочу создать тестовое приложение с CEF4.Я успешно установил компонент CEF4Delphi (github.com/salvadordf/CEF4Delphi) в C ++ Builder. И я хочу создать демонстрационный проект JSExtension delphi в C ++ Builder.

Я пытаюсь установить функцию для члена, но каждый раз получаю одну и ту же ошибку:

[Ошибка 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; 

Как это сделать правильно?

Я использую компонент CEF4Delphi (github.com/salvadordf/CEF4Delphi) в C ++ Builder. В демонстрационном проекте delphi JSExtension он работает хорошо, но я не могу собрать версию C ++ той же самой демонстрации. C ++ использует интерфейсы delphi, и я не знаю, как правильно его использовать. Мне нужно назначить свою функцию для функции-члена для GlobalCEFApp-> OnWebKitInitialized =?

Ответы [ 2 ]

3 голосов
/ 22 марта 2019

Функции-члены должны соответствовать классу, в котором они находятся.

Так что вам нужно использовать &TheClassOfTheFunction::GlobalCEFApp_OnWebKitInitialized.

2 голосов
/ 22 марта 2019

Событие TCefApplication::OnWebKitInitialized объявлено с использованием типа TOnWebKitInitializedEvent, который объявлен в единице uCEFInterfaces.pas как:

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

CEF определяет DELPHI12_UP в Delphi / C ++ Builder2009 и более поздние версии.

Вы не сказали, какую версию C ++ Builder вы используете.

  • Если вы используете C ++ Builder 2007 или более раннюю версию,Событие OnWebKitInitialized ожидает указатель на нестатический метод класса .

  • Если вы используете C ++ Builder 2009+, событие OnWebKitInitialized ожидает анонимный метод вместо.

Поскольку вы упоминаете, что пытались использовать _di_TOnWebKitInitializedEvent, который существует, только если TOnWebKitInitializedEvent является анонимнымТип метода, я должен предположить, что вы используете C ++ Builder 2009 +.

В C ++ анонимные методы в стиле Delphi требуют специальной обработки, которую Embarcadero задокументировал:

Какобрабатывать анонимные методы Delphi в C ++

Вам нужно обернуть GlobalCEFApp_OnWebKitInitialized(), чтобы использовать его как обработчик анонимных событий.Для этого у вас есть несколько вариантов в зависимости от того, используете ли вы классический компилятор Borland Win32 / OSX или один из более новых основанных на Clang компиляторов .

  • Classic : Вы должны написать функтор, который реализует интерфейс TOnWebKitInitializedEvent:

    class TWebKitInitRef : public TCppInterfacedObject<TOnWebKitInitializedEvent>
    {
    public:
        INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
        void __fastcall Invoke() { GlobalCEFApp_OnWebKitInitialized(); }
    };
    
    GlobalCEFApp->OnWebKitInitialized = _di_TOnWebKitInitializedEvent(new TWebKitInitRef());
    
  • Clang : Вы можете использовать лямбду C ++:

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