Вызов функции в приложении Delphi из c ++ dll

У меня есть dll для управления сетью, написанная на C ++ с функциями-обертками на C, которая требует процедуры из прилагаемого приложения Delphi для отправки данных по сети.

Я передаю указатель на функцию в C ++ dll, чтобы он мог вызывать процедуру в приложении delphi.

Вот то, что я думал, что будет работать, но привел к EAV в DLL:

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

Решение

Функция 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;

Тогда вы также можете воздержаться от использования @ оператор, когда вы звоните.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]