использование функции обратного вызова delphi в C dll

#c #delphi #dll #callback

#c #delphi #dll #обратный вызов

Вопрос:

Я без проблем использую C dll в программе Delphi XE2. Одна из функций DLL принимает функцию в качестве аргумента.

Вот прототип функции:

 var
 LMX_MySetOption: function(LmxHandle: LMX_HANDLE;
                             eOption: _LMX_SETTINGS;
                            callback: TCallBackProcedure): LMX_STATUS cdecl 
                                                {$IFDEF WIN32} stdcall {$ENDIF};
  

Исходный прототип функции на C был:

 LMX_STATUS LMX_SetOption(LMX_HANDLE LmxHandle, LMX_SETTINGS eOption, 
                                               const void *pSetting);
  

TCallBackProcedure определяется следующим образом:

 type
 TCallBackProcedure = procedure(bla : Pointer) stdcall;
  

Я вызываю функцию таким образом:

 LMX_MySetOption(LmxHandle, LMX_OPT_HEARTBEAT_EXIT_FUNCTION, UserExitRoutine);
  

UserExitRoutine определяется следующим образом:

 procedure UserExitRoutine(bla : Pointer) stdcall;
begin
...
end;
  

Это не работает (нарушение доступа)
Я не могу изменить C dll.

Большое спасибо за любую идею!

Комментарии:

1. TCallbackProcedure и const void *pSetting мне кажется, что они не совпадают.

Ответ №1:

Если это процедура C, не используйте stdcall, используйте cdecl .

И вы можете просто объявить это

  function LMX_MySetOption(LmxHandle: LMX_HANDLE;
                             eOption: _LMX_SETTINGS;
                            callback: Pointer): LMX_STATUS;cdecl;external 'yourmodule.dll'; 

procedure callback(bla:Pointer);cdecl;
begin
   //Some code
end;

LMX_MySetOption(LmxHandle, LMX_OPT_HEARTBEAT_EXIT_FUNCTION, @callback);
  

Это должно сработать … если это не так, возможно, вы не знаете точное количество параметров, которые имеет функция…

Комментарии:

1. Спасибо, но это не работает. Сигнатура функции обратного вызова объявляется так же, как в исходном заголовочном файле C: typedef void (LMX_CALLBACK *HeartbeatExit_pfn)(void *pVendorData); . LMX_CALLBACK определяется так, как __stdcall если бы был определен _WIN32 .

2. Возможно, pVendorData ссылается на структуру, которая требует дополнительных байтов, и пытается записать область памяти, которая не зафиксирована … другого объяснения у меня для вас нет.

3. Большое спасибо, на самом деле это работает, просто dll не вызвала обратный вызов, когда я этого ожидал!