Domanda

sto scrivendo due processi che utilizzano C # e WCF per uno e C ++ e WWSAPI per il secondo. Voglio essere in grado di definire l'indirizzo utilizzato per la comunicazione tra i due in un unico luogo e hanno entrambi C # e C ++ usarlo. È possibile?

Il più vicino Sono venuto sta definendo la costante in un IDL, quindi utilizzando sugli istituti e TLBIMP di farlo in una DLL che può essere consumato da C #. Tuttavia questo non sembra per esporre la costante, o almeno io non riesco a capire come farlo farlo. Forse è limitata a definizioni di tipo solo.

Altri suggerimenti?

È stato utile?

Soluzione

C # e C ++ sono diversi modelli per le costanti. In genere, la costante sarà nemmeno essere emessa nel risultante C ++ binario -. È sostituito automaticamente dove è necessaria la maggior parte del tempo

Invece di utilizzare la costante, fanno una funzione che restituisce la costante, che è possibile P / Invoke da C #.

Così,

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

diventa

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

, che si dovrebbe essere in grado di P / Invoke da C #.

Altri suggerimenti

È possibile creare un progetto C ++ / CLI separata e definire tutte le costanti in un file .h. Ad esempio, creare progetto ++ / CLI libreria di classi C chiamato "ConstantBridge" e un progetto C # denominato "CSharpProgram":

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"

Ora, avere la "CSharpProgram" riferimento al progetto il progetto "ConstantBridge". I suoi altri progetti C ++ nativo può semplicemente #include "Constants.h".

Fino a quando si fa riferimento a solo literals del progetto ConstantBridge, una dipendenza di runtime non verrà generato. È possibile verificare utilizzando ILSpy o ILDASM. const in C # e literal in C ++ / CLI sono copiato "letteralmente" al sito di chiamata durante la compilazione.

Non era felice con le altre soluzioni per il mio caso d'uso in modo codificato di una soluzione leggermente hacky che sembra adattarsi alla richiesta originale meglio; una costante in un unico file che può essere integrato in sia un C # e un progetto C ++ ...

  1. Le informazioni sulla versione in un file con estensione cs, in una posizione comune.

In questo modo:

// 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. Includi in C # progetto utilizzando Add Existing Item ... [Aggiungi Come Link]
  2. Includi nel progetto C ++ (in un file cpp) con un #include

In questo modo:

//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. di riferimento in C # con: MyAppVersion.Number
  2. di riferimento in C ++ con: MyAppVersion::Number

Quando ho dovuto fare quella roba in passato, ho semplicemente aggiunto un passo di pre-compilazione in più per il processo di compilazione che crea automagicamente un file da un altro.

Dato che i vostri costanti sarà probabilmente all'interno di una classe in C #, è possibile utilizzare che del file di origine:

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

Questo vi darà:

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

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

Ora, ottenendo Visual Studio per eseguire questo passo non è qualcosa che so fare. Dovrete indagare se o non è ancora possibile. Gli strumenti di elaborazione del testo Unixy sono davvero vale la pena scaricare. Ho CygWin installato su alcune scatole ma, per qualcosa di questo localizzato, si potrebbe ottenere via con i singoli pacchetti GnuWin32 .

Si potrebbe probabilmente fare un lavoro simile in PowerShell, ma io non sono davvero esperto in questo.


Ora che è un po 'un ripiego così mi permetto di suggerire un modo forse meglio per voi particolare domanda. Non utilizzo una costante a tutti. Inserire l'indirizzo in un file di configurazione e avere il vostro codice C # e C ++ lo lesse in fase di avvio.

In questo modo, si arriva a condividere il valore in modo indolore e E 'configurabile nel caso in cui si volesse cambiare in futuro.

Un'alternativa più facile ad un metodo per ogni costante può essere una classe contenente le costanti come proprietà dell'istanza. È possibile creare in C # ed esporlo tramite interfacce COM in C ++. Questo è più facile e meno soggetto a errori di P / Invoke, dal momento che non c'è bisogno di preoccuparsi di ottenere tutti i tipi e nomi a destra -. È tutto fatto per voi dal compilatore

. Nota: non ho provato questo, sto solo ipotizzando che esso dovrebbe lavoro

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top