我有一个用于delphy pascal项目的c ++ dll,我想创建一个c#项目来使用它。 dll返回一个接口对象,我现在卡在如何实现dllImport可识别的C#接口上。我有帕斯卡的代码,有效。另外,我无法访问dll的c ++源代码。
这是delphy部分:
interface
uses
IdGlobal;
type
// TIdBytes = array of Byte;
TBUF2 = array[0..1] of Byte;
TBUF3 = array[0..2] of Byte;
TBUF4 = array[0..3] of Byte;
PBUF4 = ^TBUF4;
TBUF6 = array[0..5] of Byte;
TBUF8 = array[0..7] of Byte;
TBUF16 = array[0..15] of Byte;
TUDPRcvRcd = record
Head: TBUF3;
DevType: Byte;
DevID: Byte;
DevIP: TBUF4;
DevMAC: TBUF6;
SoftVer: TBUF2;
HardVer: TBUF2;
DevName: TBUF16;
CHK: Byte;
end;
ReceiveDataEvent = procedure(aData: TIdBytes) of object;
ListRecive = procedure(aData: TIdBytes; aMac: PChar) of object;
ILhm = interface
function SearchDev: Integer; stdcall;
function SetRcvSearchResultProc(aReceiveDataEvent: ReceiveDataEvent ): Boolean; stdcall;
function ConnectDev(aMac, aIp, aPort, aPsd: PChar): Boolean; stdcall;
function RemoveDev(aMac: PChar): Boolean; stdcall;
function SendDataByMac(aData: TIdBytes; aMac: PChar): Boolean; stdcall;
function SetRcvDevDataProc(aListRecive: ListRecive ): Boolean; stdcall;
end;
function ControllerInit: ILhm; stdcall; external 'controller.dll' name 'ControllerInit';
implementation
end.
直到现在我在c#项目中写了这个
[DllImport("controller.dll",
//EntryPoint = "ControllerInt", SetLastError = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern ILhm ControllerInit();
public delegate object ReceiveDataEvent (byte[] aData);
public delegate object ListRecive(byte[] aData, string aMac);
public interface ILhm
{
int SearchDev();
bool SetRcvSearchResultProc(ReceiveDataEvent aReceiveDataEvent);
bool ConnectDev(string aMac, string aIp, string aPort, string aPsd);
bool RemoveDev(string aMac);
bool SendDataByMac(byte[] aData, string aMac);
bool SetRcvDevDataProc(ListRecive aListRecive);
}
我收到有关错误定义PInvoke的错误或:
Additional information: The runtime has encountered a fatal error. The address of the error was at 0x7221dd74, on thread 0x305c. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
谢谢!
答案 0 :(得分:0)
长话短说 - 你的DLL与C#不兼容。
Delphi接口不能在C#中使用,除非:
它们派生自IInterface
(在COM中称为IUnknown
),并且您在C#端使用COM互操作。
通过声明一个C风格的结构来伪造C#端的接口,该结构包含一个指向接口方法的vtable(一个C风格的函数指针数组)的指针。然后,无论Delphi接口在哪里,您都可以使用指向该外部结构的指针。
此外,您的两种事件类型ReceiveDataEvent
和ListRecive
正在使用与C#完全兼容的特定于Delphi的功能(procedure of object
),因此您对代理的使用对他们不起作用。使用C风格的函数指针或COM风格的事件接口。
Delphi风格的动态数组,如TIdBytes
,根本不兼容C#,甚至COM也不兼容。您需要使用静态数组,C风格动态数组或COM SafeArrays。
此外,您的代码中的错误是DLL正在使用stdcall
调用约定,但您的C#导入正在使用cdecl
。
简而言之,您应该在可以直接在C#中使用它之前重新设计DLL。如果这不是一个选项,那么至少在它周围编写一个COM包装器,然后将其导入到C#中。