Khan
Khan

Reputation: 516

Calling a Delphi DLL from C# containing Pointer in struct not working

I have a delphi dll that is defined like this

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;

I converted to C# like this :

[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);

The call is like this :

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

It is asking to open a channel and writes it in conn. It returns false. So I can't get through. The conn objects returns null. I know that the server is receiving my call.

I think that it has something to do with the struct C# that has a wrong type. I'm pretty new to unmanaged stuff so if anyone can help getting thru.

I have only the dll. Thanks

Upvotes: 2

Views: 2741

Answers (3)

maxedmelon
maxedmelon

Reputation: 251

Try using a char (NULL terminated string) and give the function a pointere to that char as an argument.

Should work for strings.

Upvotes: 2

Russell Troywest
Russell Troywest

Reputation: 8776

I'm not sure if this is your problem but I notice you are just using string in your dllimport. It appears that the default marshalling 'style' for strings is "A COM-style BSTR with a prefixed length and Unicode characters". You need a null terminating string. If that is the issue then use the MarshalAs attribute to set the marshalling type for the pIPAddr parameter:

[MarshalAs(UnmanagedType.LPWStr)]

Like this:

[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);

Upvotes: 0

RobS
RobS

Reputation: 3857

This may or may not help you but, in your C# code you use UInt32 (32-bit unsigned integer) for tSSL_connect.sock (and in the SSLCLT_Connect prototype) whereas the Delphi header defines it as Integer (32-bit signed integer).

If this doesn't work then the alternative is to write a quick wrapper in delphi that converts between the tSSL_connect record and its fields such that it can be accessed by C#.

Upvotes: 0

Related Questions