Question

J'écris deux processus en utilisant C # et WCF pour un et C ++ et WWSAPI pour le second. Je veux être en mesure de définir l'adresse utilisée pour la communication entre les deux en un seul endroit et ont C # et C ++ utiliser. Est-ce possible?

Le plus proche que je suis venu est de définir la constante dans un IDL, puis en utilisant MIDL et TLBIMP pour l'obtenir dans une DLL qui peut être consommé par C #. Toutefois, cela ne semble pas exposer la constante, ou du moins je ne peux pas comprendre comment le faire faire. Peut-être qu'il se limite aux définitions de type.

Toutes les autres suggestions?

Était-ce utile?

La solution

C # et C ++ ont des modèles différents pour les constantes. En règle générale, la constante ne sera même pas émis dans le résultat C ++ binaire -. Il est automatiquement remplacé où il est nécessaire la plupart du temps

Au lieu d'utiliser la constante, faire une fonction qui retourne la constante, que vous pouvez P / Invoke de C #.

Ainsi,

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

devient

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

que vous devriez être en mesure de P / Invoke de C #.

Autres conseils

Vous pouvez créer un projet distinct C ++ / CLI et définir toutes vos constantes dans un fichier .h. Par exemple, créer projet de classe C ++ / CLI Library appelé "ConstantBridge" et un projet C # appelé "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"

, ont la référence du projet « CSharpProgram » le projet « ConstantBridge ». Vos autres projets C ++ natif peut simplement #include "Constants.h".

Tant que vous faites référence uniquement literals du projet ConstantBridge, une dépendance d'exécution ne sera pas généré. Vous pouvez vérifier en utilisant ILSpy ou ildasm. const en C # et literal en C ++ / CLI sont copié "littéralement" sur le site d'appel lors de la compilation.

n'a pas été heureux avec les autres solutions pour mon cas d'utilisation si codée une solution légèrement hacky qui semble correspondre mieux la demande initiale; une constante dans un fichier qui peut être intégré dans deux C # et un projet C ++ ...

  1. Informations de version dans un fichier .cs, dans un endroit commun.

Comme ceci:

// 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. Inclure dans le projet C # en utilisant Ajouter un élément existant ... [Ajouter comme lien]
  2. Inclure dans le projet de C (dans un fichier cpp) avec un #include

Comme ceci:

//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. Référence en C # avec: MyAppVersion.Number
  2. Référence en C ++ avec: MyAppVersion::Number

Quand j'ai eu à faire ce genre de choses dans le passé, je l'ai simplement ajouté une étape de pré-compilation supplémentaire au processus de construction qui crée automagiquement un fichier d'une autre.

Étant donné que vos constantes seront probablement dans une classe en C #, vous pouvez l'utiliser comme fichier source:

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

Cela vous donnera:

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

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

Maintenant, pour Visual Studio pour effectuer cette étape n'est pas quelque chose que je sais comment faire. Vous devrez déterminer si oui ou non il est même possible. Les outils de traitement de texte unixy sont vraiment une valeur de téléchargement. Je CygWin installé sur quelques boîtes, mais pour quelque chose de ce localisé, vous pouvez vous en sortir avec personne paquets GnuWin32 .

Vous pourriez probablement faire un travail similaire dans PowerShell mais je suis pas vraiment bien versé dans cela.


Maintenant, qui est un peu bidouille donc peut-je suggérer une meilleure façon peut-être pour vous question particulière. Ne pas utiliser une constante du tout. Mettez l'adresse dans un fichier de configuration et votre C # et le code C lu au démarrage.

De cette façon, vous obtenez de partager la valeur sans douleur et il est configurable dans le cas où vous voulez jamais changer à l'avenir.

Une alternative plus facile à un procédé pour chaque constante peut être une classe contenant les constantes que les propriétés d'instance. Vous pouvez créer en C # et l'exposer via des interfaces COM à C ++. C'est plus facile et moins sujette aux erreurs que P / Invoke, puisque vous n'avez pas à vous soucier de tous les types et les noms à droite -. Tout cela est fait pour vous par le compilateur

Note:. Je n'ai pas essayé, je ne spéculant que devraient travail

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top