Frage

Ich schreibe zwei Prozesse mit C # und WCF für ein und C ++ und WWSAPI für die zweite. Ich möchte in der Lage, die Adresse zu definieren, zwischen den beiden in einem einzigen Ort und haben sowohl C # für die Kommunikation verwendet wird, und C ++ verwenden. Ist das möglich?

Die nächstgelegene ich gekommen bin ist die Konstante in einem IDL-Definition dann MIDL und TLBIMP mit in eine DLL zu erhalten, die von C # verbraucht werden kann. Doch dies scheint nicht die Konstante zu belichten, oder zumindest kann ich nicht herausfinden, wie es so zu tun zu machen. Vielleicht ist es nur auf Typ-Definitionen beschränkt.

Alle anderen Vorschläge?

War es hilfreich?

Lösung

C # und C ++ haben unterschiedliche Modelle für Konstanten. Typischerweise wird die Konstante nicht einmal in der resultierenden C ++ binäre emittiert werden. - es wird automatisch ersetzt, wo er die meiste Zeit benötigt wird,

Anstatt die Konstante verwenden, stellen Sie eine Funktion, die die Konstante zurückgibt, dem Sie P / Invoke von C #.

So

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

wird

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

, die Sie sollten in der P / Invoke von C # können.

Andere Tipps

Sie können ein separates C ++ / CLI-Projekt erstellen und alle Ihre Konstanten in einer .h Datei definieren. Zum Beispiel, C ++ / CLI-Klassenbibliothek Projekt namens "ConstantBridge" und ein C # Projekt mit dem Namen "CSharpProgram" erstellen:

constants.h

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"

Nun hat den „CSharpProgram“ Projektverweis des „ConstantBridge“ Projekt. Ihre andere native C ++ Projekte können einfach #include "Constants.h".

Solange Sie Referenz nur literals vom ConstantBridge Projekt wird eine Laufzeitabhängigkeit nicht erzeugt werden. Sie können mit ILSpy oder ildasm überprüfen. const in C # und literal in C ++ / CLI sind kopiert "buchstäblich" auf den Anruf Website während der Kompilierung.

Was mit den anderen Lösungen für meinen Anwendungsfall nicht glücklich, so eine etwas hacky Lösung codierte up, die die ursprüngliche Anforderung besser zu passen scheinen; eine Konstante in einer Datei, die in gebaut werden kann beide ein C # und C ++ Projekt ...

  1. Versionsinformationen in einer CS-Datei, in einem gemeinsamen Ort.

Wie folgt aus:

// 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. Fügen Sie in C # Projekt mit Vorhandenes Elemente hinzufügen ... [A Link]
  2. Fügen Sie in C ++ Projekt (in einer CPP-Datei) mit einem #include

Wie folgt aus:

//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. Referenz in C # mit: MyAppVersion.Number
  2. Referenz in C ++ mit: MyAppVersion::Number

Als ich hatte das Zeug in der Vergangenheit zu tun, habe ich einfach einen zusätzliche Vorkompilierung Schritt zu dem Build-Prozess hinzugefügt, die eine Datei von einem anderen automatisch erstellt.

Da Ihre Konstanten wahrscheinlich innerhalb einer Klasse in C # wird, Sie, dass als Quelldatei verwenden können:

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

Dies gibt Ihnen:

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

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

Nun, Visual Studio bekommen, diesen Schritt zu führen ist nicht etwas, was ich weiß, wie zu tun ist. Sie müssen untersuchen, ob oder nicht, es ist sogar möglich. Die Unixy Textverarbeitung Tools sind wirklich wert, heruntergeladen. Ich habe CygWin auf ein paar Kisten installiert, aber für etwas so lokalisiert, Sie mit individuellen wegkommen könnte GnuWin32 Pakete .

Sie könnten wahrscheinlich einen ähnlichen Job in Powershell tun, aber ich bin nicht wirklich gut, dass versiert.


Nun, da ein bisschen eine Flickschusterei ist so kann schlage ich eine möglicherweise bessere Art und Weise für Sie bestimmte Frage. Nicht Verwendung eine Konstante überhaupt. Legen Sie die Adresse in eine Konfigurationsdatei und Ihre C # und C ++ Code einlesen beim Start.

Auf diese Weise erhalten Sie schmerzfrei den Wert teilen und es konfigurierbar ist, falls Sie es jemals in Zukunft geändert werden soll.

Eine einfachere Alternative zu einem Verfahren für jede Konstante kann eine Klasse sein, die Konstanten wie zB Eigenschaften. Man könnte es in C # erstellen und über COM-Schnittstellen zu C ++ aussetzen. Das ist einfacher und weniger fehleranfällig als P / Invoke, da Sie Angst haben nicht über alle Typen und Namen immer recht -. Alles für Sie vom Compiler getan

. Hinweis: Ich habe nicht versucht, ich spekuliere nur, dass es sollte Arbeit

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top