Я пытаюсь научиться создавать библиотеки DLL на С++, поэтому я мог легко пропустить что-то сверхъестественное.
В настоящее время я создаю DLL с C++, а затем загружаю ее в тестовую среду, написанную на C#.
Среда тестирования написана на C#, потому что я считаю, что Windows Forms проще всего использовать для создания прототипов графических интерфейсов.
У меня есть определение в моей DLL (С++)
#define BUILD_FOR_TESTBED
и функция, которую я сделал, чтобы определить, было ли оно определено
//header file
extern "C" _declspec(dllexport) extern bool WasBuiltForTestbed();
//source file
bool WasBuiltForTestbed()
{
#ifdef BUILD_FOR_TESTBED
return true;
#endif // BUILD_FOR_TESTBED
#ifndef BUILD_FOR_TESTBED
return false;
#endif // BUILD_FOR_TESTBED//
}
Затем я загружаю функцию в тестовую среду (C#)
[DllImport(LIBRARY_PATH, CharSet = CharSet.Unicode)]
public static extern bool WasBuiltForTestbed();
И пишем в консоль в тестовой среде
Console.WriteLine("Built For Testbed: " + WasBuiltForTestbed());
Независимо от того, что я делаю, WasBuiltForTestbed() возвращает true после загрузки в среду тестирования.
В: Мой вопрос: что мне здесь не хватает, чтобы функция всегда возвращала true? Как сделать так, чтобы функция возвращала значение независимо от того, был ли определен BUILD_FOR_TESTBED?
Тесты, которые я пробовал до сих пор:
«Короткое замыкание» функции и ее прямое «возвращение» true или false. Он по-прежнему возвращает только true.
bool WasBuiltForTestbed() { return false; }
Очистка сборки библиотеки (C++) и среды тестирования (C#). Затем восстановление
Изменение имени функции WasBuiltForTestbed() на WasBuiltForrTestbed() в библиотеке. Среде тестирования не удалось загрузить функцию, поэтому она определенно находит то, что считает функцией, и оценивает ее.
Любая помощь приветствуется.
.NET использует 4 байта bool
, но Visual C++ использует 1 байт bool
. Таким образом, вам понадобится директива маршалинга, чтобы сообщить маршалеру, что приходит всего один байт. Как бы то ни было, он просто упорядочивает 3 байта мусора в дополнение к вашему bool
. Мусор обычно не равен нулю, поэтому ваша функция возвращает true
.
Добавьте это в файл DllImport.
[return:MarshalAs(UnmanagedType.I1)]
Что касается того, почему .NET решила сделать bool
4 байта, вероятно, основная причина заключается в том, чтобы отдать предпочтение взаимодействию с C++ API Windows, которые используют 4 байта BOOL
, а не в реализации Visual C++ стандартного C++, которая использует 1 -байт bool
.
(Почему предостережения? Ну, стандарт C++ на самом деле не определяет размер bool
...)
В С# вы получите true, если число не равно нулю. Итак, по какой-то причине ноль, установленный в С++, не является нулем в С#. это часто происходит, когда размер переменной различается между С++ и С#. Итак, попробуйте: ((int)WasBuiltForTestbed()).ToString(), чтобы узнать, какое число возвращается.