简体   繁体   English

从C ++ DLL调用delphi应用程序中的函数

[英]Calling a function in a delphi app from c++ dll

I have a network management dll written in C++ with wrapper functions in C which requires a procedure from the accompanying Delphi app to send data over the network. 我有一个用C ++编写的网络管理dll,其中包含C的包装函数,它需要随附的Delphi应用程序提供的过程才能通过网络发送数据。

I am passing a function pointer to the C++ dll so that it can call the procedure in the delphi app. 我将函数指针传递给C ++ dll,以便它可以在delphi应用程序中调用该过程。

Here's what I thought would work but resulted in an EAV in the dll:- 这是我认为可行的方法,但导致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 C ++部分

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

The C++ function receives a function pointer of type C ++函数接收类型的函数指针

void(*APtrToSendData)(int,int,void *)

But your Delphi code passes this: 但是您的Delphi代码可以通过以下代码:

procedure ( AUID, AType, ASize: Integer; ABuffer: Pointer ) of object;

This is simply not compatible. 这根本不兼容。 The Delphi procedural type has an extra parameter, uses the register calling convention, and is a method of object. Delphi程序类型具有一个额外的参数,使用register调用约定,并且是一种对象方法。

You need to declare TNetMgrSendData as follows: 您需要按以下方式声明TNetMgrSendData

TNetMgrSendData = procedure(uid, len: Integer; buffer: Pointer); cdecl;

You make life hard for yourself when you declared CreateNetMgr to receive an untyped pointer. 当您声明CreateNetMgr接收无类型的指针时,您会为自己的生活变得艰难。 It would be much better to declare it like this: 像这样声明它会更好:

function CreateNetMgr(APtrToSendData: TNetMgrSendData): Pointer; cdecl; 
  external DLL_NAME;

Then you can also refrain from using the @ operator when you call it. 然后,您也可以在调用它时避免使用@运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM