2016-05-13 2 views
-1

У меня есть (C/C++) DLL, которую я вызываю DLLImport в проект C#. Эта библиотека имеет этот метод:Передача указателей из неуправляемого кода без модификатора

int __stdcall Connect(OUT int *p_sessionID, IN BYTE mode, IN BYTE comport, IN char *servername, IN DWORD serverport); 

Я пытался несколько способов «перевести» его на C#, но тот, который я нахожу ближе:

[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect", CallingConvention = CallingConvention.StdCall)] 
private static extern unsafe int CS1_Connect(out IntPtr p_sessionID, byte mode, byte comport, string servername, int serverport); 

Я пытаюсь вызвать так:

IntPtr connection; 
var i = Connect(out connection, 1, 0, "192.0.0.1", 1982); 

Но я всегда получаю следующее сообщение об ошибке:

Дополнительная информация: вызов для функции PInvoke «DllImportTest! DllImportTest.Program :: Connect» имеет несбалансированный стек. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой сигнатуре. Убедитесь, что соглашение о вызове и параметры сигнатуры PInvoke соответствуют целевой неуправляемой подписи.

Я знаю, что могу связаться с DLL, потому что у меня есть другой метод, который работал нормально.

Что я делаю неправильно?

Спасибо.

+0

Первый аргумент должен быть 'out int'. Но это не объясняет предупреждение MDA, вам придется предположить, что документация функции устарела. Нет другого способа проверить, все украшения были удалены. Вы должны связаться с автором библиотеки для получения поддержки. –

+0

Это объясняет MDA, если цель была 64 бит –

+0

Не совсем, IntPtr растет, а первые 4 args передаются через регистры вместо стека. –

ответ

0

Ваш первый параметр переведен неверный.

OUT int *p_sessionID 

Здесь OUT макрос, который указывает семантику для читателя. Макрос расширяет его до нуля. И поэтому после предварительной обработки у вас есть:

int *p_sessionID 

Это переводится как

out int sessionID 

в вашем C#.

Вам не нужно объявлять функцию небезопасной, удалите ее. И последний параметр без знака. Возможно, вы захотите перейти на uint.

Правильный перевод был бы поэтому быть:

[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect", 
    CallingConvention = CallingConvention.StdCall)] 
private static extern int CS1_Connect(
    out int sessionID, 
    byte mode, 
    byte comport, 
    string servername, 
    uint serverport 
); 

Если вы все еще получаете стека несбалансированного сообщения, то вы знаете, что неуправляемая функция не имеет подписей, что Вы процитировали в этом вопросе.

+0

Я уже пробовал. Но у меня такая же ошибка. И если я не использую небезопасные, я не могу скомпилировать код. В последнем параметре был выбран uint. Я пропустил заклинание, когда я печатал здесь. –

+0

Это не игра проб и ошибок. Это не путь. Если функция в моем ответе приводит к предупреждению дисбаланса стека, вы знаете, что объявление функции C, которое у вас есть, не соответствует фактической функции. –

+0

Хорошо. Спасибо за помощь! –

Смежные вопросы