2010-07-14 11 views
5

Ich habe einen Legacy-Code in C (nicht C++) implementiert. Ich möchte in der Lage sein, einige Methoden in diesem C-Code von meinem C# -Code (unter Windows) aufzurufen. Was wäre der beste Ansatz, um zwischen den beiden Sprachen zu kommunizieren? Bitte beachten Sie, dass die Methode in C nicht zustandslos ist. Wir müssen zwei Methoden aufrufen:im Gespräch mit C von C#

  1. Initialisierung() => Dies wird die Datenstruktur initialisieren und Daten von Dateien in den Speicher laden. Diese Methode wird einmal aufgerufen.
  2. ComputeSomething (Parameter) => es wird mehrere Aufrufe von C# zu dieser Methode geben.

Hinweis: Diese beiden Methoden tatsächlich mehrere andere Methoden aufrufen, aber diese sind nur die beiden Methoden, die wir zu C# aussetzen möchte (der Code ist ziemlich kompliziert, deshalb haben wir in den Hafen C# nicht wollen)

Ich konnte den c-Code in Visual Studio importieren und in der Lage, den Code erfolgreich zu kompilieren. Ich weiß, dass wir den C-Code wahrscheinlich als Windows-Dienst implementieren können, aber ich suche nach einer Lösung, die es uns ermöglicht, die C-Methode direkt von C# aus aufzurufen. Irgendwelche Hinweise wird sehr geschätzt! (ist COM Interop in Bezug auf was ich suche zu tun?)

+0

warum nicht Ihre Methoden auf C# implementieren? – Luiscencio

+0

Was ist die kompilierte Ausgabe Ihres C-Codes? Wenn es eine .dll ist und COM unterstützt, sollte es einfach möglich sein, eine "Referenz hinzufügen" aus Visual Studio zu erstellen und zu der DLL-Datei zu navigieren. – Nate

+1

Wenn Sie dies noch nicht getan haben, erscheint das Umbrechen Ihrer Funktionen in einer COM-Klasse und die Verwendung von .NET/COM-Interop als zu viel Arbeit/Overkill. Ich würde diese zwei C-Funktionen einfach in eine DLL setzen und mit P/Invoke auf sie zugreifen, wie von Jason Evans vorgeschlagen. – stakx

Antwort

10

Klingt wie Sie P/Invoke dafür verwenden können. Schauen Sie sich diese Seite für Tipps:

http://www.pinvoke.net/

Versuchen Sie auch, SO für die Beratung über P/Invoke und Google für

C# Benutzer pinvoke Aufruf c Code

Ich habe keine alle technischen Beispiele zur Hand, aber ich habe einige .NET-Code geschrieben, der Win32-APIs über P/Invoke aufgerufen. Der schwierige Teil besteht darin, die Methodensignaturen beim Übergeben von Parametern zu korrigieren. This könnte Ihnen da draußen helfen.

+0

Danke für die Antwort! Weißt du, ob P/Invoke für meine Situation funktionieren würde, in der die Methodenaufrufe statusbehaftet sind? (Sie müssen initialize aufrufen, um Daten zu laden, bevor eine andere Methode aufgerufen wird.) Bleiben die globalen Variablen für den nachfolgenden Methodenaufruf im Speicher? – mwong

+0

Hand aufs Herz, ich weiß es nicht. Da der C-Code jedoch in den Adressraum des .NET-Codes geladen werden muss und resident bleiben muss (nicht jedes Mal dynamisch geladen), würde ich erwarten, dass die Werte des C-Codes gleich bleiben. Ich fürchte, das ist etwas, mit dem du experimentieren musst. :(Lass uns wissen, was du herausgefunden hast und ob meine Logik völlig falsch ist! –

2

Die neueste Version von Visual Studio ermöglicht Ihnen das Schreiben von C++ - Code, der unsichere Funktionen aufrufen kann, aber weiterhin mit CLR verwaltetem Code interagiert. Sie nennen dies "Implizites PInvoke" oder "C++/CLR". Lesen Sie den MSDN-Artikel "Using C++ Interop", um mehr zu erfahren.

Verwalteter Code kann nicht direkt unmanaged aufgerufen werden, daher benötigen Sie Wrapper-Funktionen, um die Speicherverwaltungsprobleme zu lösen und zwischen .NET-Objekten und den Datenstrukturen Ihrer Anwendung zu übersetzen. Über den obigen Link lesen Sie den Abschnitt "Gewusst wie: Umbrechen der nativen Klasse zur Verwendung durch C#".

1

Hier ist eine Lösung. Die Lösung ermöglicht es, die C# -Funktion von C aufzurufen, indem Sie Ihre Funktion mit dem Attribut [DllExport] dekorieren (gegenüber P/Invoke DllImport).

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

C# -Code

class Test 
{ 
    [DllExport("add", CallingConvention = CallingConvention.StdCall)] 
    public static int Add(int left, int right) 
    { 
     return left + right; 
    } 
} 

C-Code

int main() 
{ 
     int z = add(5,10); 
     printf("The solution is found!!! Z is %i",z); 
     return 0; 
}