C++ от C#: функция C++ (в DLL) возвращение false, но C# думает, что это верно!

Я думаю, что это охвачено в MSDN, см. Регистрировать Приложение к Протоколу .

URL

11
задан 24 November 2009 в 20:25
поделиться

2 ответа

Попробуйте [return: MarshalAs (UnmanagedType.I1)] . По умолчанию C # interop маршалирует C # bool как Win32 BOOL , что совпадает с int , а C ++ bool это один байт AFAIR. Таким образом, маршалинг C # по умолчанию ожидает, что возвращаемое значение будет BOOL в регистре eax , и собирает ненулевой мусор, потому что C ++ bool возвращается в и .

16
ответ дан 3 December 2019 в 06:21
поделиться

Опубликованный фрагмент кода не работает. Если бы это было скомпилировано с помощью компилятора C ++, тогда имя функции было бы ? Foo @@YA_NXZ и ваш код C # никогда не смогут его найти. Соглашение о вызовах также важно, оно не используется по умолчанию (CallingConvention.StdCall), если вы не сообщите компилятору. И где-то вы должны были указать компоновщику экспортировать функцию.

Начните с объявления экспортируемой функции, чтобы она была совместима с атрибутами P / Invoke по умолчанию:

extern "C" __declspec(dllexport) 
bool __stdcall Foo() {
    return false;
}

Следующая проблема заключается в том, что компилятор C ++ использует только один байт для хранения бул. Машинный код, сгенерированный для вашего оператора return:

013D138E  xor         al,al

Маршаллер P / Invoke, однако, предположит, что это 32-битное целое число, и проверит значение регистра eax. Либо объявите тип возвращаемого значения функции как int или BOOL, либо используйте атрибут [return: MarshalAs (UnmanagedType.U1)] в объявлении C #.

3
ответ дан 3 December 2019 в 06:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: