Я думаю, что это охвачено в MSDN, см. Регистрировать Приложение к Протоколу .
URL
Попробуйте [return: MarshalAs (UnmanagedType.I1)]
. По умолчанию C # interop маршалирует C # bool
как Win32 BOOL
, что совпадает с int
, а C ++ bool
это один байт AFAIR. Таким образом, маршалинг C # по умолчанию ожидает, что возвращаемое значение будет BOOL
в регистре eax
, и собирает ненулевой мусор, потому что C ++ bool
возвращается в и
.
Опубликованный фрагмент кода не работает. Если бы это было скомпилировано с помощью компилятора 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 #.