[Ms VS 2005] C++ Dll in C# einbinden
-
Die Fehlermeldung ist klar.
dllimport.call(); gibt es auch nicht.
Siehe was Konrad Rudolph geschrieben hat.
Solltest Du es nicht verstehen hast Du probleme mit Grundlagen.
In C++ kann man auch keine Funktion verwenden ohne sie zu deklarieren.static void Main(string[] args) { call(); }
ohne jetzt zu wissen ob man damit eine printf aus der DLL machen kann.
Normalerweise gibt man aus einer DLL einfach den String zurück und gibt in in NET aus.
-
Durch das
__declspec(dllexport) void call();
sollte die Methode schon exportiert werden. Vermutlich wird sie aber dekoriert (liegt, glaub ich, an der Aufrufkonvention).
Versuch malextern "C" __declspec(dllexport) void call();
dann sollte es eigentlich klappen.
Die "def" datei bruacht der Linker, isr klar. Mir DllImport wird aber dynamisch gelinkt, ähnlich wie in C/C++ mit LoadLibrary(...) und GetProcAddress(...), deshalb wird keine "def" Datei benötigt, sondern nur die Dll.
-
Durch das
__declspec(dllexport) void call();
sollte die Methode schon exportiert werden. Vermutlich wird sie aber dekoriert (liegt, glaub ich, an der Aufrufkonvention).
Versuch malextern "C" __declspec(dllexport) void call();
dann sollte es eigentlich klappen.
Die "def" datei bruacht der Linker, isr klar. Mir DllImport wird aber dynamisch gelinkt, ähnlich wie in C/C++ mit LoadLibrary(...) und GetProcAddress(...), deshalb wird keine "def" Datei benötigt, sondern nur die Dll.Unix-Tom schrieb:
In C++ kann man auch keine Funktion verwenden ohne sie zu deklarieren.
Natürlich kann man das, außerdem ist die Methode "call" deklariert...
Oh, sorry für den doppelten Post, wollte eigentlich nur editieren...
-
Unix-Tom schrieb:
Die Fehlermeldung ist klar.
dllimport.call(); gibt es auch nicht.
Dachte ich auch erst.
Aber schau mal, wie die Klasse heißt, in der die Funktionsdeklaration liegt.
Herb schrieb:
Die "def" datei bruacht der Linker, isr klar. Mir DllImport wird aber dynamisch gelinkt, ähnlich wie in C/C++ mit LoadLibrary(...) und GetProcAddress(...), deshalb wird keine "def" Datei benötigt, sondern nur die Dll.
Nein, da verwechselst Du etwas. Die 'DEF'-Datei wird vom Linker für das Erstellen der Exporttabelle benötigt. Wenn eine DLL keine Exporttabelle besitzt, dann kann sie auch nicht dynamisch verlinkt werden, es sei denn, man gibt den Einsprungpunkt direkt als Adresse an, was auch möglich wäre: Die Exportdefinitionstabelle wird von der Funktion 'GetProcAddress' benötigt.
Aber generell gilt: Ohne 'DEF'-Datei keine Exporte. Theoretisch sollte es dem Compiler möglich sein, diese Datei on-the-fly aus den '__declspec(dllexport)'-Direktiven zu erstellen. Aber hier tritt dann genau das beschriebene Problem auf, dass der Compiler die Namen „mangled“. Um das zu umgehen führt, soweit ich weiß, kein Weg drumherum, die DEF-Datei selbstzuschreiben.
-
Herb schrieb:
Unix-Tom schrieb:
In C++ kann man auch keine Funktion verwenden ohne sie zu deklarieren.
Natürlich kann man das
Und wie?
-
Aber generell gilt: Ohne 'DEF'-Datei keine Exporte. Theoretisch sollte es dem Compiler möglich sein, diese Datei on-the-fly aus den '__declspec(dllexport)'-Direktiven zu erstellen. Aber hier tritt dann genau das beschriebene Problem auf, dass der Compiler die Namen „mangled“. Um das zu umgehen führt, soweit ich weiß, kein Weg drumherum, die DEF-Datei selbstzuschreiben.
Genau dafür ist dann eben die
extern "C"
direktive - so wird beim __declspec(dllexport) das Name Mangeling ausgeschaltet.
Zusammengefasst:
Funktionen können auf folgende Arten exportiert werden:
a.) mit *.def File (es findet KEIN name mangeling statt)
b.) mit __declspec(dllexport) (es findet name mangeling statt, wenn dies nicht erwünscht ist die direktive extern "C" verwenden).-> Generell können aber auch funktionen mit name mangeling aufgerufen werden. Der funktions name ist jedoch nicht allzu leserlich. (Der name könnte mit dem DllImport Attribute gemappt werden.)
Ich benütze für die Überprüfung, ob funktionen exportiert wurden und unter welchem namen immer den Dependency Walker: http://www.dependencywalker.com/
Nur um Missverständnissen vorzu beueugen:
Auf auf der managed Seite wird NUR die DLL mit den exportierten Funktionen benötigt (und natürlich die abhänigen DLLs). Kein *.lib, *.def oder *.h File.Noch ein Wort zum name mangeling:
Das name mangeling wird vo C++ Compiler eingesetzt um z.B. Überladungen von Funktionen zuzulassen. So wird die Signatur (funktions name, typen und anzahl der parameter) ein den name hineincodiert.Grüsse
Simon
-
Moin!
Also es funktioniert mittlerweile.
Das ganze sieht folgendermassen aus.DLL:
namespace test { extern "C" { __declspec(dllexport) void call() { printf("Hello World!"); } } }
C#:
class dllimport { [DllImport ("c++_csharp.dll")] public static extern void call(); } class program { static void Main(string[] args) { dllimport.call(); } }
Ausgabe funktioniert 1a!
-
Hallo Simon,
ich dachte bisher (hatte noch nie damit gearbeitet), dass das 'extern "C"' nur für den Import von Symbolen korrekt funktioniert, nicht für den Export. Dass es auch so funktioniert, ist natürlich schön, da man sich die DEF-Datei erspart.
-
Konrad Rudolph schrieb:
Herb schrieb:
Unix-Tom schrieb:
In C++ kann man auch keine Funktion verwenden ohne sie zu deklarieren.
Natürlich kann man das
Und wie?
int add(int a, int b) { return a + b; } int main() { return add(a,b); }
Hab die funktion "add" nicht deklariert - die Definition reicht, sie muß nur vor dem Aufruf stehen.
Mit der "def" Datei hast du natürlich recht.
-
Herb schrieb:
Konrad Rudolph schrieb:
Herb schrieb:
Unix-Tom schrieb:
In C++ kann man auch keine Funktion verwenden ohne sie zu deklarieren.
Natürlich kann man das
Und wie?
int add(int a, int b) { return a + b; } int main() { return add(a,b); }
Hab die funktion "add" nicht deklariert - die Definition reicht, sie muß nur vor dem Aufruf stehen.
Das da oben ist (auch) eine Deklaration (*jede* Definition ist eine Deklaration). Siehe C++-Standard, Sektion 3 Abs. 5 und 3.1 Abs 2.