2

我有一个这样定义的delphi dll

type
tSSL_connect          = packed record
        pssl            : Pointer;
        pctx            : Pointer;
        sock            : Integer;
end;

function SSLCLT_Connect(pIPAddr: PChar; 
    iPort: Integer;
    var pConn: tSSL_connect;
    iTimeout: Integer;
    bEnableNonBlockingMode: BOOL = TRUE): BOOL;
    stdcall; external cltdll;

我像这样转换为C#:

[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi, Pack=1)]
        public unsafe struct tSSL_connect
        {
            public IntPtr pssl;
            public IntPtr pctx;
            public UInt32 sock;
        };

[DllImport("cltdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool SSLCLT_Connect(string pIPAddr, UInt32 iPort, ref tSSL_connect pConn, UInt32 iTimeout, bool bEnableNonBlockingMode);

电话是这样的:

tSSL_connect conn = new tSSL_connect();
btest = SSLCLT_Connect("127.0.0.1", 3858, ref conn, 1500, false);

它要求打开一个通道并将其写入 conn。它返回假。所以我过不去。conn 对象返回 null。我知道服务器正在接听我的电话。

我认为这与类型错误的 struct C# 有关。我对不受管理的东西很陌生,所以如果有人可以帮助通过。

我只有dll。谢谢

4

3 回答 3

2

尝试使用 char(以 NULL 结尾的字符串)并给函数一个指向该 char 的指针作为参数。

应该适用于字符串。

于 2009-09-21T16:56:18.667 回答
0

我不确定这是否是您的问题,但我注意到您只是在 dllimport 中使用字符串。字符串的默认编组“样式”似乎是“具有前缀长度和 Unicode 字符的 COM 样式 BSTR”。您需要一个空终止字符串。如果这是问题,则使用 MarshalAs 属性为 pIPAddr 参数设置编组类型:

[MarshalAs(UnmanagedType.LPWStr)]

像这样:

[DllImport("cltdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern bool SSLCLT_Connect([MarshalAs(UnmanagedType.LPWStr)]string pIPAddr, UInt32 iPort, ref tSSL_connect pConn, UInt32 iTimeout, bool bEnableNonBlockingMode);
于 2009-07-08T14:31:27.207 回答
0

这可能对您有帮助,也可能对您没有帮助,但是,在您的 C# 代码中,您使用 UInt32(32 位无符号整数)作为 tSSL_connect.sock(以及 SSLCLT_Connect 原型),而 Delphi 标头将其定义为整数(32 位有符号整数)。

如果这不起作用,那么替代方法是在 delphi 中编写一个快速包装器,在 tSSL_connect 记录及其字段之间进行转换,以便 C# 可以访问它。

于 2009-07-06T12:26:14.820 回答