从 Pascal 到 C# 的代码翻译

Code translation from pascal to c#

我有一个在 delphy pascal 项目中使用的 c++ dll,我想创建一个 c# 项目来使用它。 dll returns 一个接口对象,我现在被困在如何实现 dllImport 识别的 C# 接口上。我有 pascal 的代码,可以用。另外,我无权访问 dll 的 c++ 源代码。

这是德尔菲部分:

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.

谢谢!

长话短说 - 您的 DLL as-is 与 C# 不兼容。

Delphi 接口不能在 C# 中使用,除非:

  • 它们派生自 IInterface(在 COM 中称为 IUnknown)并且您在 C# 端使用 COM 互操作。

  • 你通过声明一个 C-style 结构来伪造 C# 端的接口,该结构包含一个指向接口方法的 vtable(C-style 函数指针的数组)的指针.然后您可以在需要 Delphi 接口的任何地方使用指向该外部结构的指针。

此外,您的两个事件类型 ReceiveDataEventListRecive 使用的 Delphi-specific 功能 (procedure of object) 与 C# 完全不兼容,所以您对代表的使用对他们不起作用。使用 C-style 函数指针或 COM-style 事件接口。

Delphi-style 动态数组,如 TIdBytes,也不与 C# 兼容,甚至与 COM 不兼容。您需要改用静态数组、C-style 动态数组或 COM SafeArrays。

此外,您的代码中的一个错误是 DLL 使用的是 stdcall 调用约定,但您的 C# 导入使用的是 cdecl

总之,你真的应该重新设计DLL,然后才能在C#中直接使用它。如果这不是一个选项,那么至少围绕它编写一个 COM 包装器,然后将其导入 C#。