Вызов DLL-библиотеки Delphi из C #, содержащей указатель в структуре, не работает

2

У меня есть dll delphi, который определен как этот

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;

Я преобразовал в С# следующим образом:

[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. Я знаю, что сервер получает мой вызов.

Я думаю, что это имеет какое-то отношение к структуре С#, которая имеет неправильный тип. Я новичок в неуправляемых вещах, поэтому, если кто-то может помочь получить через.

У меня есть только dll. Благодаря

Теги:
pointers
struct
dllimport

3 ответа

2

Попробуйте использовать char (NULL завершенную строку) и дать функции pointere для этого char в качестве аргумента.

Должен работать для строк.

0

Я не уверен, что это ваша проблема, но я заметил, что вы просто используете строку в своем dllimport. Похоже, что по умолчанию "стиль" для строк - "BSTR COM-стиля с префиксом длины и символы Unicode". Вам нужна строка с нулевым завершением. Если это проблема, используйте атрибут 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);
0

Это может или не поможет вам, но в коде С# вы используете UInt32 (32-разрядное целое число без знака) для tSSL_connect.sock(и в прототипе SSLCLT_Connect), тогда как заголовок Delphi определяет его как Integer (32-разрядная подпись целое число).

Если это не сработает, альтернативой является запись быстрой обертки в delphi, которая преобразует между записью tSSL_connect и ее полями, так что к ней можно получить доступ с помощью С#.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню