DLLImport: передача короткого параметра типа - PullRequest
0 голосов
/ 16 ноября 2010

Я пытаюсь передать параметр короткого типа в неуправляемую функцию C ++, импортированную из DLL. В моем C ++ DLL-коде у меня есть следующая функция:

__declspec(dllexport)void ChangeIcon(char *executableFile, char *iconFile,
    UINT16 imageCount)
{
    // Some code, doesn't matter
}

В C # управляемом коде я импортирую эту функцию со следующим кодом:

[DllImport("IconChanger.dll")]
static extern void ChangeIcon(string executableFile, string iconFile,
    ushort imageCount);

А потом я называю это:

ushort imageCount = 2;
ChangeIcon("filePath", "iconPath", imageCount);

Приложение выполняет функцию просто отлично; однако появляется сообщение со следующим текстом:

Помощник по управляемой отладке «PInvokeStackImbalance» обнаружил проблему в «foo.exe». Дополнительная информация: вызов функции PInvoke 'bar.IconChanger :: ChangeIcon' разбалансирует стек. Это вероятно потому, что управляемая подпись PInvoke не совпадает с неуправляемой целевой подписью. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи.

Если я не передам последний параметр, сообщение не появится, поэтому оно должно быть из-за передачи короткого типа. Я тоже пытался с int, появляется то же сообщение.

Очевидно, что я делаю что-то не так при передаче этого числового параметра. Как сопоставить параметры между двумя?

Ответы [ 2 ]

3 голосов
/ 16 ноября 2010

Убедитесь, что соглашение о вызовах совпадает. Если вы не укажете соглашение о вызовах, предполагается StdCall. Однако для C / C ++ стандартное соглашение о вызовах - Cdecl. Так что либо используйте __stdcall в вашей функции C ++:

void __declspec(dllexport) __stdcall ChangeIcon(char *executableFile, char *iconFile,
    UINT16 imageCount)
{
    // Some code, doesn't matter
}

или укажите CallingConvention.Cdecl на DllImport:

[DllImport("IconChanger.dll", CallingConvention = CallingConvention.Cdecl)]

В качестве примечания: UInt16 не является CLS-совместимым типом, поэтому вам, вероятно, потребуется Int16 , если вам необходимо это соответствие.

0 голосов
/ 16 ноября 2010

Поскольку вы используете char * в параметрах функций C ++, я рекомендую вам импортировать функцию следующим образом: [DllImport ("IconChanger.dll", CallingConvention = CallingConvention.Cdecl)] static extern void ChangeIcon (строка [MarshalAs (UnmanagedType.LPStr) исполняемый файл, строка [MarshalAs (UnmanagedType.LPStr))

...