[c#] DLL-Wrapper generieren lassen

Tagchen Xperten,

mit dem vorhaben eine nicht .NET DLL in meinem Programm benutzen zu wollen möchte ich diese nun möglichst sauber, am besten mit einer automatisch generierten Schnittstellen-Klasse nutzen.

Gibt es möglichkeiten zu externen DLLs für c# solche Schnittstellen automatisch generieren zu lassen?

Wenn nicht:
Was wäre da die effizienteste Möglichkeit an die Funktionen dieser DLL zu kommen.

MfG
Passer

Hallo!

Eine Automatik gibt es m.W. nach nicht. Normale Win32-DLLs enthalten einfach nicht genug Metainformation, um das vernünftig und allgemeingültig zu bewerkstelligen.

Am sinnvollsten ist es daher wohl, wenn du Dir eine (oder mehrere, ich weiss ja nicht, was alles in diese DLL gepackt wurde) Klasse definierst, die dann die P/Invoke-Deklarationen der Funktionen Deiner DLL als private oder intern enthält.
Dazu dann die entsprechenden öffentlichen Methoden, in denen die DLL-Funktionen aufgerufen werden.

Darum, Dir das richtige Marshalling für die Funktionsaufrufe selbst zu überlegen, wirst Du aber nicht herumkommen.

Microsoft hat aber zu dem Thema ja eine Menge Info (Start z.B. hierüber: http://msdn.microsoft.com/library/deu/default.asp?ur…) und wenn es um Standard-Dlls geht, dann ist http://pinvoke.net eine ganz gute Anlaufstelle.

Gruß,
Martin

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Eine Automatik gibt es m.W. nach nicht. Normale Win32-DLLs
enthalten einfach nicht genug Metainformation, um das
vernünftig und allgemeingültig zu bewerkstelligen.

Mist

Darum, Dir das richtige Marshalling für die Funktionsaufrufe
selbst zu überlegen, wirst Du aber nicht herumkommen.

Mist, denn die DLL befindet sich auch in der Entwicklung, so dass der Wrapper immer wiede rneu angepasst werden müsste (was imho leichter wäre, würde ich da jedesmal nur eine Automatik drüber laufen alssen müssen)

Danke für die Links, vielleicht find ich da ja noch eine passende Alternative.

MfG
Passer

Eine Automatik gibt es m.W. nach nicht. Normale Win32-DLLs
enthalten einfach nicht genug Metainformation, um das
vernünftig und allgemeingültig zu bewerkstelligen.

Mist

Darum, Dir das richtige Marshalling für die Funktionsaufrufe
selbst zu überlegen, wirst Du aber nicht herumkommen.

Mist, denn die DLL befindet sich auch in der Entwicklung, so
dass der Wrapper immer wiede rneu angepasst werden müsste (was
imho leichter wäre, würde ich da jedesmal nur eine Automatik
drüber laufen alssen müssen)

Wenn die DLL noch in Entwicklung ist, dann sollte aber vorher schon klar sein, welche Funktionen enthalten sind und wie die Schnittstelle aussieht!
Wenn da VHIT programmiert wird (Vom Hirn Ins Terminal) dann hast Du’s sicher schwer, wenn sich laufend alles ändert, aber mit entsprechender Planung sollte man die Schnittstellen schon weitgehend konstant festlegen können, damit nicht immer wieder der komplette Wrapper angepasst werden muss…

Danke für die Links, vielleicht find ich da ja noch eine
passende Alternative.

MfG
Passer

Gruß,
Martin

Problem mit Pointern

also soweit habe ich jetzt über DLLImport für einige Methoden die Schnittstellen angelegt.

Das war bei Standarddatentypen ja soweit kein Problem. Für einie Methoden habe ich allerdings Rümpfe a la

MyObj* getMyObj(DeinObjekt *instance, NochEinObjekt *instance2)

Und wenn ich ehrlich bin habe ich keine Ahnung, wie ich da die DLLImport Syntaxx aussehen soll (also für Pointer, die ich ohnehin nicht mag)

MfG Passer

Normalerweise definierst du Dir eine entsprechende C# Klasse für die jeweiligen Zeigertypen (also in Deinem Beispiel 3 Klassen: MyObj, DeinObjekt, NochEinObjekt) und spezifizierst dann bei der DLLImport Deklaration, ob die Parameter in, out oder in/out Parameter sind, indem Du ggf. die Parameter als „ref“ oder „out“ deklarierst.

Kommt aber jeweils auf die konkrete Verwendung an, geht also auch wieder nicht allgemein, wenn man nur sieht, dass eine Funktion einen Zeiger auf irgendwas bekommt…

Gruß,
Martin

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

1 Like

Kommt aber jeweils auf die konkrete Verwendung an, geht also
auch wieder nicht allgemein, wenn man nur sieht, dass eine
Funktion einen Zeiger auf irgendwas bekommt…

Mhh wäre ne idde, habe grad die Aufbauten dieser gezeigten Objekte gefunden. Sind im Prinzip „nur“ structs.

Blöde Frage:
Lässt sich so ein struct einfach nachbauen, indem ich eine Klasse definiere und dort die Structinhalte reinschreibe
bsp:
struct MeinObjet{
int groesse
int laenge

}
public class MeinObjet{
int groesse
int laenge
}

was dann hiesse, ich würde solch einer methode quasi eine Instanz von MeinObjekt übergeben (bzw man übergibt ja die referenz) und der würde das dann als „Pointer“ interpretieren.

(Jetzt weiss ich auch wieder, warum ich C/c++ den rücken gekehrt habe:wink:

Kommt aber jeweils auf die konkrete Verwendung an, geht also
auch wieder nicht allgemein, wenn man nur sieht, dass eine
Funktion einen Zeiger auf irgendwas bekommt…

Mhh wäre ne idde, habe grad die Aufbauten dieser gezeigten
Objekte gefunden. Sind im Prinzip „nur“ structs.

Blöde Frage:
Lässt sich so ein struct einfach nachbauen, indem ich eine
Klasse definiere und dort die Structinhalte reinschreibe
bsp:
struct MeinObjet{
int groesse
int laenge

}
public class MeinObjet{
int groesse
int laenge
}

was dann hiesse, ich würde solch einer methode quasi eine
Instanz von MeinObjekt übergeben (bzw man übergibt ja die
referenz) und der würde das dann als „Pointer“ interpretieren.

Jup, letztlich funktioniert’s so.
Statt der structs kannst Du Dir auch Klassen erstellen, dann hast Du’s meistens einfacher, weil Klassen reference-Typen sind und structs value-Typen. Beim Marshalling in die bzw. von der DLL verhalten sich die 2 nämlich unterschiedlich (z.B. brauchst Du bei der Klasse i.d.R. kein „ref“, beim struct aber schon, wenn es nicht nur ein Eingabeparameter sein soll).
Das Ganze ist aber auch auf dem MSDN-Link irgendwo beschrieben…

(Jetzt weiss ich auch wieder, warum ich C/c++ den rücken
gekehrt habe:wink:

:smile:

Viel Erfolg,
Martin

Kommt aber jeweils auf die konkrete Verwendung an, geht also
auch wieder nicht allgemein, wenn man nur sieht, dass eine
Funktion einen Zeiger auf irgendwas bekommt…

Da hab ich doch gleich nochmal eine Frage…

habe leider noch eine Methode entdeckt, die einen Zeiger auf einObjekt zurückgibt.

dieses Objekt muss ich soweit ich das bis jetzt sehe nicht manipulieren. Es wird aber in einer anderen methode als Argument benötigt.

Was kann man da machen???

Sorry, wenn ich mit den Fragen nerve, aber diese dllimport geschichte istw as neues für mich. Sicherlich was ganz einfaches, wenn man es ein paar mal gemacht hat )

MfG
PAsser

Du müsstest eigentlich einfach den IntPtr wieder reinstopfen können, sowas in etwa:

[DllImport("MyDll.dll")]
static extern IntPtr GetObject(string name);
 
[DllImport("MyDll.dll")]
static extern void DoSomethingWithMyObject(IntPtr pObj);
 
...
IntPtr myObj = GetObject("Bla");
...
DoSomethingWithMyObject(myObj);

In Deinem C# Programm sagst Du also, dass Dir egal ist, was da eigentlich als Zeiger kommt, Du musst das Teil nur weiterreichen.

Evtl. musst Du noch etwas mit der Speicherverwaltung in .NET aufpassen, damit Dir der GC den Zeiger nicht verschiebt (Stichwort: GCHandle.AddrOfPinnedObject()), aber wenn Abruf und Weitergeben des Objekts sehr zeitnah erfolgen, dann sollte es i.d.R. ohne weiteren Voodoo gehen.

Gruß,
Martin

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]