Вопрос

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

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

Любые другие предложения?

Это было полезно?

Решение

C # и C ++ имеют различные модели для констант. Как правило, константу даже не будет выделяться в результате C ++ Binary - он автоматически заменяется там, где он необходим большую часть времени.

Вместо того, чтобы использовать константу, сделайте функцию, которая возвращает константу, которую вы можете P / вызывать из 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 / вызывать из C #.

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

Вы можете создать отдельный проект C ++ / CLI и определить все ваши константы в .h файл. Например, создать проект библиотеки класса C ++ / CLI под названием «ConstantBridge» и проект C #, называемый «CSHARPPROGR»:

Константы

namespace Constants
{
    const int MAGIC_NUMBER = 42;
}

// String literals must be defined as macros
#define MAGIC_PHRASE "Hello World"

// Since stirngs must be macros it's arguably more consistent 
// to use `define` throughout. This is for demonstration purpose.

ConstantBridge.h.

#include "Constants.h"

namespace ConstantBridge { public ref class ConstantBridge {
public:
    // The use of the `literal` keyword is important
    // `static const` will not work
    literal int kMagicNumber = Constants::MAGIC_NUMBER;
    literal String ^ kMagicPhrase = MAGIC_PHRASE;
};}

Csharpprogram.cs.

Console.WriteLine(ConstantBridge.kMagicNumber); // "42"
Console.WriteLine(ConstantBridge.kMagicPhrase); // "Hello World"

Теперь иметь проект «CSHARPPROGR» проект «Константабридж». Ваши другие нативные проекты C ++ могут просто #include "Constants.h".

До тех пор, пока вы ссылаетесь Только literalс от ConstantBridge Проект, зависимость выполнения не будет сгенерирована. Вы можете проверить, используя Ilspy. или Илды. const в C # и literal в C ++ / CLI скопирован «буквально» на сайт вызова во время компиляции.

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

  1. Информация о версии в файле .cs, в общем месте.

Так:

// Version.cs
public static class MyAppVersion
{
    //build
    public static string Number = "1.0";
    public static string Phase = "Alpha";

    //configuration (these are the build constants I use, substitute your own)
#if BUILD_SHIPPING
    public static string Configuration = "Shipping";
#elif BUILD_DEVELOPMENT
    public static string Configuration = "Development";
#elif BUILD_DEBUG
    public static string Configuration = "Debug";
#else
    "build type not defined"
#endif
}
  1. Включите в проект C # с использованием добавления существующего элемента ... [Добавить в качестве ссылки
  2. Включают в проекте C ++ (в файле .CPP) с #include

Так:

//include version information into a .cpp
#define class namespace
#define public
#define static
#define string const char*
#include "..\..\Version.cs" //or to where-ever your file is
;
#undef class
#undef public
#undef static
#undef string
  1. Ссылка в C # с: MyAppVersion.Number
  2. Ссылка на C ++ с: MyAppVersion::Number

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

Поскольку ваши константы, вероятно, будут в классе в 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;

Теперь, получая визуальную студию для выполнения этого шага - это не то, что я знаю, как сделать. Вам придется расследовать, можно ли ли это даже возможно. Инструменты обработки текста Unixy действительно стоит загружать. у меня есть Cygwin установлен на несколько коробок, но, для чего-то этого локализованного, вы можете сойти с индивидуальным Gnuwin32 пакеты.

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


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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top