Frage

Ich habe einige C-Code ANSI-Standard, der autorisiert ist. Was das bedeutet, ist, dass, obwohl ich die Quelle haben, kann ich nicht in eine andere Sprache übersetzen, noch ändern Argumente nennen, da diese Maßnahmen die Behörde nicht verfälscht werden. Es gibt mehr als 150 Funktionen.

kann ich zufällige Änderungen vornehmen, wie die Dateinamen von .C zu CPP ändern, so dass es von Visual Studio 2009 der C ++ Compiler kompiliert mit, was ich getan habe. Compiler-Direktiven und so können auch hinzugefügt werden. Ich kann auch eine Wrapper-Schicht durchlaufen, falls erforderlich.

Eine weitere Einschränkung ist mein Unternehmen nicht nicht will, dass mir das unsicher verwenden Schlüsselwort in jedem C # -Code.

Ich brauche auf diesen Funktionen von einem C # Programm zu erhalten.

Eine typische C / C ++ Funktion sieht wie folgt aus:
double SomeFunction(double a, double[3] vec, double[3][3] mat);
Wo der Inhalt des Arrays ist manchmal Eingang, manchmal Ausgang und selten beides.

Ich versuchte zunächst, eine nicht verwaltete DLL zu machen (mit den Funktionen markiert Extern C). Funktionen mit nur einfachen Argumente (int, double) hat gut funktioniert, aber ich konnte nicht feststellen, wie die Arrays Marschall. (Eigentlich habe ich einige Beispiel-Code finden, aber es war extrem komplex und unvernünftig 150-mal zu duplizieren.)

Ich habe dann versucht, zwei Projekte in der gleichen Lösung, ein in C ++ und die andere in C #. In dem C ++ Projekt, habe ich eine verwaltete Funktion, die nur die ursprüngliche Funktion aufgerufen, die als nicht verwaltete markiert wurde. Das war sehr sauber und einfach, und wieder, einfache Argumente hat gut funktioniert. Aber für Arrays, konnte ich nicht finden, wie die Argumenttypen für die C # C ++ Grenze entsprechen zu machen:
Argument '2': cannot convert from 'double[]' to 'double*'
(Und wie oben erwähnt, kann ich nicht unsicher verwenden, um einen Zeiger zu bekommen).

Sicher, was ich versuche möglich zu tun müssen.
Was ist der beste Weg, um diese Funktionen zu bekommen?
(Beispielcode die obige Funktion wäre wirklich cool.)

War es hilfreich?

Lösung

Beispiel C / C ++ Implementierung:

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;
}

Beispiel C # Nutzung:

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);

Andere Tipps

Wenn Sie die extern und P / Invoke-Lösung zu arbeiten bekommen, ist ein Wrapper wahrscheinlich die beste Wahl. Erstellen Sie eine verwaltete C ++ DLL, die sowohl verwalteten und nicht verwalteten Code verwendet. Fügen Sie eine .NET-Klasse auf diese DLL, die nur eine dünne Hülle über die Funktionen in Ihrem C-DLL ist. Ihre C # -Code können die C ++ .NET-Klasse aufrufen, was wiederum nach vorn auf die C-Funktionen.

So können Sie die Übersetzung zwischen .NET und nicht verwalteten Code schreiben können, sich selbst, anstatt sich auf die Laufzeit zu verlassen, um es für Sie tun.

Verwendung swig, wird es Ihre pinvoke für Sie

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