我正在创建一个像下面的C dll。
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* fun accept an argument status_callback which is a function pointer*/
TEST_API void fun(void(*status_callback)(int));
#ifdef __cplusplus
}
#endif
和乐趣实现为:
void fun(void(*status_callback)(int)) {
status_callback(0);
}
在对象pascal上使用这个dll与delphi xe如下所示我在回调函数的地址遇到了访问冲突的崩溃
type
TStatusCallBack = procedure( Value: Integer ); stdcall;
T_fun = procedure(cb : TStatusCallback );
procedure BCallBack( Value: Integer ); stdcall;
begin
BStatus := value;
end;
begin
_fun(BCallBack);
end;
实例化代码:
DLLHandle := LoadLibrary( ‘mylib.dll’ );
if (DLLHandle > HDLL_ERROR) then
begin
_fun := T_fun(GetProcAddress( DLLHandle, 'fun');
end;
有什么问题?既然我是C的noobie任何评论?
我们缺少重要的细节。我们无法在C ++方面看到fun
的实现,我们无法看到你如何在Delphi方面声明_fun
。
但是我们可以看到一个错误。回调的调用约定不匹配。 C ++代码将回调定义为__cdecl
。您需要使用cdecl
来匹配Delphi端,而不是stdcall
。
同样地,我希望你的Delphi代码获得_fun
的调用约定错误。再次它应该是cdecl
但错误消息表明你的声明实际上是register
。
总之,对Delphi代码进行以下更改:
cdecl
。cdecl
。fun
的进口为cdecl
。查看编辑,检查LoadLibrary
返回值的错误是错误的。返回值为零表示错误。比较等于零以测试失败。
调用GetProcAddress
时也无法检查错误。您需要处理返回nil
的情况。同样,这可能会导致运行时出现错误,并且代码已写入。
编辑中的代码显示我的所有猜测都是正确的。解决方案详见上述要点。