Как я совместно использую константу между кодом C++ и C#?

Я пишу два процесса с помощью C# и WCF для одного и C++ и WWSAPI для второго. Я хочу смочь определить адрес, используемый для коммуникации между двумя в единственном месте и иметь и C# и C++, используют его. Действительно ли это возможно?

Самое близкое я приехал, определяет константу в IDL, затем с помощью MIDL и TLBIMP для получения его в DLL, который может быть использован C#. Однако это, кажется, не выставляет константу, или по крайней мере я не могу выяснить, как заставить ее сделать так. Возможно, это ограничено для ввода определений только.

Какие-либо другие предложения?

9
задан dlanod 30 June 2010 в 02:02
поделиться

3 ответа

C # и C ++ имеют разные модели для константы. Обычно константа даже не генерируется в результирующем двоичном файле C ++ - она ​​автоматически заменяется там, где она необходима большую часть времени.

Вместо использования константы создайте функцию, которая возвращает константу, которую вы можете P / Invoke из C #.

Таким образом,

#include <iostream>
const double ACCELERATION_DUE_TO_GRAVITY = 9.8;
int main()
{
     std::cout << "Acceleration due to gravity is: " << 
         ACCELERATION_DUE_TO_GRAVITY;
}

становится

#include <iostream>
extern "C" double AccelerationDueToGravity()
{
    return 9.8;
}
int main()
{
     std::cout << "Acceleration due to gravity is: " << 
         AccelerationDueToGravity();
}

, который вы должны иметь возможность P / Invoke из C #.

5
ответ дан 4 December 2019 в 12:59
поделиться

Когда мне приходилось делать это в прошлом, я просто добавлял дополнительный этап предварительной компиляции в процесс сборки, который автоматически создает один файл из другого.

Поскольку ваши константы, вероятно, будут внутри класса на C #, вы можете использовать их в качестве исходного файла:

MyClass.cs:
    class MyClass {
        public const int NUM_MONTHS = 12;    //COMMON
        public const int YEAR_BASE = 1900;   //COMMON
    }

grep '//COMMON' MyClass.cs
    | sed -e 's/^ *public const [a-z][a-z]*/#define/'
          -e 's/ *= */ /'
          -e 's/;.*$//'
    >MyClass.h
grep '//COMMON' MyClass.cs | sed -e 's/ *public //' -e 's/;.*$/;/' >MyClass.hpp

Это даст вам:

MyClass.h:
    #define NUM_MONTHS 12
    #define YEAR_BASE 1900

MyClass.hpp:
    const int NUM_MONTHS = 12;
    const int YEAR_BASE = 1900;

Теперь я не знаю, как заставить Visual Studio выполнить этот шаг делать. Вам нужно будет выяснить, возможно ли это вообще. Инструменты обработки текста UNIXy действительно стоит загрузить. У меня CygWin установлен на нескольких компьютерах, но для чего-то такого локализованного можно обойтись отдельными пакетами GnuWin32 .

Вы, вероятно, могли бы проделать аналогичную работу в PowerShell, но я не очень разбираюсь в этом.


Это немного путаница, так что могу я предложить, возможно, лучший способ ответа на ваш конкретный вопрос. Ни в коем случае не используйте константу . Поместите адрес в файл конфигурации и пусть ваш код C # и C ++ прочитает его при запуске.

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

1
ответ дан 4 December 2019 в 12:59
поделиться

Более простой альтернативой методу для каждой константы может быть класс, содержащий константы в качестве свойств экземпляра. Вы можете создать его на C# и предоставить его через интерфейсы COM для C++. Это проще и менее подвержено ошибкам, чем P/Invoke, так как вам не нужно беспокоиться о том, чтобы получить все типы и имена правильно - все это делается за вас компилятором.

Примечание: Я не пробовал это, я только предполагаю, что это должно работать.

0
ответ дан 4 December 2019 в 12:59
поделиться
Другие вопросы по тегам:

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