从结构中无效的C#调用包含Pointer的Delphi DLL

时间:2009-07-03 20:34:17

标签: c# delphi struct pointers dllimport

我有一个像这样定义的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。 它返回false。所以我无法通过。 conn对象返回null。我知道服务器正在接听我的电话。

我认为它与具有错误类型的struct C#有关。我对非托管的东西很陌生,所以如果有人能帮助你通过。

我只有dll。感谢

3 个答案:

答案 0 :(得分:2)

尝试使用char(以NULL结尾的字符串)并将该函数作为参数赋予该char函数。

应该适用于字符串。

答案 1 :(得分:0)

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

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

答案 2 :(得分: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);