从c ++ dll调用delphi应用程序中的函数

时间:2014-01-02 15:22:04

标签: c++ delphi dll firemonkey

我有一个用C ++编写的网络管理dll,其中包含C语言中的包装函数,需要附带Delphi应用程序的程序才能通过网络发送数据。

我正在传递一个指向C ++ dll的函数指针,以便它可以在delphi应用程序中调用该过程。

这是我认为会起作用但在dll中导致EAV: -

Delphi Part:

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.

C ++ Part

#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;
}

1 个答案:

答案 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;

然后,您也可以在调用时禁止使用@运算符。