我有一个用C ++编写的网络管理dll,其中包含C语言中的包装函数,需要附带Delphi应用程序的程序才能通过网络发送数据。
我正在传递一个指向C ++ dll的函数指针,以便它可以在delphi应用程序中调用该过程。
这是我认为会起作用但在dll中导致EAV: -
unit NetMgrWrapper;
interface
uses System.Classes;
type
TNetMgrSendData =
procedure ( AUID, ASize: Integer; ABuffer: Pointer ) of object;
TNetMgr = class ( TObject )
private
fNetworkManager : Pointer;
public
constructor Create ( const AOnSendData: TNetMgrSendData );
destructor Destroy; override;
end;
implementation
const
DLL_NAME = 'NetMgr.dll';
function CreateNetMgr ( APtrToSendData: Pointer ): Pointer; cdecl; external DLL_NAME;
procedure FreeNetMgr ( ANetMgr: Pointer ); cdecl; external DLL_NAME;
constructor TNetMgr.Create ( const AOnSendData: TNetMgrSendData );
begin
fNetworkManager := CreateNetMgr ( @AOnSendData );
end;
destructor TNetMgr.Destroy;
begin
FreeNetMgr ( fNetworkManager );
end;
end.
#include "cbase.h"
#include "buffer.h"
#include "INatMgr.h"
class NetMgr : public INetManager
{
private:
void (*ExternalSendData) (int, int, void *);
public
NetMgr ( void (*PtrToSendData) (int,int,void *) )
{
ExternalSendData = PtrToSendData;
}
virtual void SendData ( int uid, const CBuffer &payload )
{
CBuffer Packet;
Packet = payload;
Packet.ResetPtr ();
ExternalSendNATData ( uid, Packet.LengthBuffer(), Packet.Ptr() );
}
}
DLL_EXPORT NetMgr CreateNetMgr ( void(*APtrToSendData)(int,int,void *) )
{
return new NetMgr ( APtrToSendData );
}
DLL_EXPORT void FreeNetMgr ( NetMgr *pNetMgr )
{
delete pNetMgr;
}
答案 0 :(得分:2)
C ++函数接收类型为
的函数指针void(*APtrToSendData)(int,int,void *)
但是你的Delphi代码传递了这个:
procedure ( AUID, AType, ASize: Integer; ABuffer: Pointer ) of object;
这完全不兼容。 Delphi过程类型有一个额外的参数,使用register
调用约定,并且是一个对象的方法。
您需要按如下方式声明TNetMgrSendData
:
TNetMgrSendData = procedure(uid, len: Integer; buffer: Pointer); cdecl;
当你声明CreateNetMgr
接收无类型指针时,你会为自己的生活变得艰难。宣布它是这样的好得多:
function CreateNetMgr(APtrToSendData: TNetMgrSendData): Pointer; cdecl;
external DLL_NAME;
然后,您也可以在调用时禁止使用@
运算符。