您的 DLL 使用了 Delphi 的两个不同特性,只有 C++Builder 支持,其他 C++ 编译器不支持:
您的回调使用of object 修饰符,这意味着可以为回调分配对象实例的非静态方法。这是在 C++Builder 中使用供应商特定的__closure 编译器扩展实现的。尽管标准 C++ 确实具有使用指向对象方法的函数指针的语法,但其实现方式与 __closure 的实现方式截然不同。
您的回调没有声明任何调用约定,因此使用 Delphi 的默认 register 调用约定。在 C++Builder 中,这对应于供应商特定的 __fastcall 调用约定(不要与 Visual C++ 的 __fastcall 调用约定混淆,后者完全不同,在 C++Builder 中实现为 __msfastcall )。
如果您只关心支持 C++Builder,那么您可以保留 DLL 代码原样,相应的 C++ 代码如下所示:
typedef void __fastcall (__closure *TOnIOChangeEvent)(TObject *Sender, int DeviceID, int iFlag);
int __stdcall LaneController_Init(TOnIOChangeEvent OnIOChangeEvent);
void __fastcall TSomeClass::SomeMethod(TObject *Sender, int DeviceID, int iFlag)
{
//...
}
TSomeClass *SomeObject = ...;
LaneController_Init(&(SomeObject->SomeMethod));
但是,如果需要支持其他C++编译器,则需要更改DLL以支持标准C/C++,例如:
type
TOnIOChangeEvent = procedure(DeviceID, iFlag: Integer; UserData: Pointer); stdcall;
function LaneController_Init(OnIOChangeEvent: TOnIOChangeEvent; UserData: Pointer): Integer; stdcall;
然后你可以在 C++ 中执行以下操作:
typedef void __stdcall (*TOnIOChangeEvent)(int DeviceID, int iFlag, void *UserData);
int __stdcall LaneController_Init(TOnIOChangeEvent OnIOChangeEvent, void *UserData);
void __fastcall TSomeClass::SomeMethod(int DeviceID, int iFlag)
{
//...
}
// note: not a member of any class. If you want to use a class
// method, it will have to be declared as 'static'...
void __stdcall LaneControllerCallback(int DeviceID, int iFlag, void *UserData)
{
((TSomeClass*)UserData)->SomeMethod(DeviceID, iFlag);
}
TSomeClass *SomeObject = ...;
LaneController_Init(&LaneControllerCallback, SomeObject);