Загрузка значения из C++ .DLL в C# всегда возвращает true

Я пытаюсь научиться создавать библиотеки 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() в библиотеке. Среде тестирования не удалось загрузить функцию, поэтому она определенно находит то, что считает функцией, и оценивает ее.

Любая помощь приветствуется.

В С# вы получите true, если число не равно нулю. Итак, по какой-то причине ноль, установленный в С++, не является нулем в С#. это часто происходит, когда размер переменной различается между С++ и С#. Итак, попробуйте: ((int)WasBuiltForTestbed()).ToString(), чтобы узнать, какое число возвращается.

jdweng 10.12.2020 17:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
157
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

.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...)

Другие вопросы по теме