Я пишу два процесса с помощью C# и WCF для одного и C++ и WWSAPI для второго. Я хочу смочь определить адрес, используемый для коммуникации между двумя в единственном месте и иметь и C# и C++, используют его. Действительно ли это возможно?
Самое близкое я приехал, определяет константу в IDL, затем с помощью MIDL и TLBIMP для получения его в DLL, который может быть использован C#. Однако это, кажется, не выставляет константу, или по крайней мере я не могу выяснить, как заставить ее сделать так. Возможно, это ограничено для ввода определений только.
Какие-либо другие предложения?
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 #.
Когда мне приходилось делать это в прошлом, я просто добавлял дополнительный этап предварительной компиляции в процесс сборки, который автоматически создает один файл из другого.
Поскольку ваши константы, вероятно, будут внутри класса на 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 ++ прочитает его при запуске.
Таким образом, вы можете безболезненно поделиться значением и , его можно настроить на случай, если вы когда-нибудь захотите изменить его в будущем.
Более простой альтернативой методу для каждой константы может быть класс, содержащий константы в качестве свойств экземпляра. Вы можете создать его на C# и предоставить его через интерфейсы COM для C++. Это проще и менее подвержено ошибкам, чем P/Invoke, так как вам не нужно беспокоиться о том, чтобы получить все типы и имена правильно - все это делается за вас компилятором.
Примечание: Я не пробовал это, я только предполагаю, что это должно работать.