Question

J'ai un code C standard ANSI qui fait autorité. Cela signifie que, même si j'ai la source, je ne peux pas traduire dans une autre langue ni modifier les arguments d'appel, car ces actions invalideraient l'autorité. Il y a plus de 150 fonctions.

Je peux apporter des modifications accessoires, telles que modifier les noms de fichiers de .C à .CPP afin qu'il soit compilé à l'aide du compilateur C ++ de Visual Studio 2009, ce que j'ai déjà fait. Les directives du compilateur et autres peuvent également être ajoutées. Je peux également passer par une couche d'emballage, si nécessaire.

Une autre restriction est que mon entreprise ne ne veut pas que j'utilise le mot clé non sécurisé dans tout code C #.

Je dois accéder à ces fonctions à partir d'un programme C #.

Une fonction C / C ++ typique ressemble à ceci:
  double SomeFunction (double a, double [3] vec, double [3] [3] mat);
Où le contenu du tableau est parfois entré, parfois sorti, et rarement les deux.

J'ai d'abord essayé de créer une DLL non gérée (avec les fonctions marquées Extern C). Les fonctions avec seulement des arguments simples (int, double) ont bien fonctionné, mais je n’ai pas pu déterminer comment structurer les tableaux. (En fait, j'ai trouvé un exemple de code, mais il était extrêmement complexe et déraisonnable de le dupliquer 150 fois.)

J'ai ensuite essayé deux projets au sein de la même solution, l'un en C ++ et l'autre en C #. Dans le projet C ++, j'ai créé une fonction managée qui vient d'appeler la fonction d'origine qui a été marquée comme non gérée. C'était extrêmement simple et propre, et encore une fois, des arguments simples ont bien fonctionné. Mais pour les tableaux, je ne trouvais pas comment faire correspondre les types d'arguments entre les limites C # à C ++:
Argument '2': impossible de convertir de 'double []' en 'double *'
(et comme mentionné ci-dessus, je ne peux pas utiliser un objet non sécurisé pour obtenir un pointeur).

Certes, ce que j'essaie de faire doit être possible.
Quel est le meilleur moyen d’obtenir ces fonctions?
(Un exemple de code utilisant la fonction ci-dessus serait vraiment cool.)

Était-ce utile?

La solution

Exemple d'implémentation C / C ++:

extern "C" __declspec(dllexport)
double SomeFunction(double a, double vec[3], double mat[3][3]) {
  double sum = a;
  for (int ix = 0; ix < 3; ++ix) {
    sum += vec[ix];
    for (int iy = 0; iy < 3; ++iy) {
      sum += mat[ix][iy];
    }
  }
  return sum;
}

Exemple d'utilisation de C #:

private void Form1_Load(object sender, EventArgs e) {
  double[] vec = new double[3];
  double[,] mat = new double[3, 3];
  for (int ix = 0; ix < 3; ++ix) {
    vec[ix] = ix;
    for (int iy = 0; iy < 3; ++iy) {
      mat[ix, iy] = (ix + 1) * iy;
    }
  }
  double sum = SomeFunction(1, vec, mat);
}
[System.Runtime.InteropServices.DllImport("cpptemp8.dll")]
private static extern double SomeFunction(double a, double[] vec, double[,] mat);

Autres conseils

Si vous ne parvenez pas à obtenir les solutions extern et P / Invoke, un wrapper est probablement votre meilleur choix. Créez une DLL C ++ gérée qui utilise à la fois du code géré et du code non géré. Ajouter une classe .NET à cette DLL qui est juste un wrapper mince sur les fonctions de votre DLL C. Votre code C # peut appeler la classe C ++ .NET, qui transmettra les fonctions C à son tour.

De cette manière, vous pouvez écrire vous-même la traduction entre le code .NET et le code non managé, au lieu de compter sur le moteur d'exécution pour le faire à votre place.

utilisez swig, il générera votre pinvoke pour vous

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