Laden...

Schwierigkeiten beim Erstellen einer Wrapperklasse für eine C++ DLL

Erstellt von dschmoegner vor 18 Jahren Letzter Beitrag vor 18 Jahren 5.343 Views
D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren
Schwierigkeiten beim Erstellen einer Wrapperklasse für eine C++ DLL

Moin,

da ich in Bezug auf Wrapperklassen für unmanaged Code keinerlei Erfahrung habe, habe ich es nach dem Beispiel aus der MSDN versucht.


[sysimport(dll="ftd2xx.dll")]
		public static extern FT_STATUS FT_Open(int deviceNumber,
												  FT_HANDLE *pHandle);

		private void Open()
		{
			stat = FT_Open(1, pHandle);
		}

Der Compiler beschwert sich, dass er den Übergabeparameter FT_HANDLE *pHandle nicht kennt. Die Methode ist so in der Headerdatei der DLL angegeben.


typedef PVOID	FT_HANDLE;
typedef ULONG	FT_STATUS;

Das ist das einzigste was ich zu FT_HANDLE in der Headerdatei finden konnte. Wenn ich jetzt in C++ coden würde, bräuchte ich ja nur die Headerdatei einbinden und alle Typdefinitionen hätten sich erledigt.
Da ich den Wald vor lauter Bäumen grad net sehe, hoffe ich ihr habt mehr Durchblick.

gruss dschmoegner

P.S. Falls mir bei der Forensuche eine Thread zu genau diesem Thema durch die Lappen gegangen sein sollte entschuldigt es bitte.

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

A
154 Beiträge seit 2005
vor 18 Jahren

Bin in dem Gebiet jetzt auch kein Fachmann.
Da er den Typ nicht kennt glaube ich du dem sagen das es ein UnmanagedType ist.
Da gibts ein Attribute [marshal(UnmanagedType.TYPE)] gefolgt von einem c# Typ.
FT_HANDLE müßte dann mit diesem ersetzten.
Type denke ich wäre hier LPVoid

Also ungefähr so. Aber ohne Gewähr 😉
[marshal(UnmanagedType.LPVoid)]uint* ptr

.

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Erst einmal danke.

Habe die grossen Fehler im Code entdeckt. War nen blöder Post. Sorry hierfür

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

Die Pointer als IntPtr deklarieren....

Dann mit Marshal.AllocGlobal den Platz reservieren

Marshal.StructureToPtr verwenden um das managed Object zu kopieren

Api aufrufen

Marshal.FreeHGlobal räumt dann wieder ab

Die Infos zu den genannten Befehlen findest Du sicher selber

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

@Programmierhans

Sorry, aber den Teil mit Api aufrufen versteh ich nicht so ganz und was ich trotz MSDN nicht so ganz verstehe ist Marshall.StructureTo().....das will mir nicht in den Kopf.


IntPtr addressOfStructure1 = ...;
TYPEATTR structure2 = ...;
Marshal.StructureToPtr(structure2, addressOfStructure1, true);

C# kennt doch keine Zeiger, wie soll ich also dem IntPtr ne Adresse geben? Muss ich die Struktur TYPEATTR selber füllen?
Wenn ich ehrlich bin kann ich mit den meisten Membern dieser Struktur nix anfangen.

gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

			//this durch deine Instanz ersetzen
			Type t=this.GetType();
			//Memory allozieren
			IntPtr ptr=Marshal.AllocHGlobal(Marshal.SizeOf(t));
			//Struktur kopieren
			Marshal.StructureToPtr(this,ptr,true);

			//Api aufruf durchführen

			//Cleanup
			Marshal.FreeHGlobal(ptr);


Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Also ungefähr so:


//Methode im DLL Header definiert
FTD2XX_API
FT_STATUS WINAPI FT_Open(
	int deviceNumber,
	FT_HANDLE *pHandle
	);

//leider weiss ich nicht wieviel Speicher FT_HANDLE 
//benötigt für
            //this durch deine Instanz ersetzen
            Type t=this.GetType();
            //Memory allozieren
            IntPtr ptr=Marshal.AllocHGlobal(Marshal.SizeOf(t));

//Struktur kopieren
            Marshal.StructureToPtr(this,ptr,true);

            //Api aufruf durchführen
            //Hier käme dann also mein Methodenaufruf rein?
            //oder der DLLImport?
            FT_Open(0, ptr);
            //Cleanup
            Marshal.FreeHGlobal(ptr);

Anscheinend übersteigt das Ganze doch meinen momentanen Kenntnisstand.
Dennoch Danke

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

So, habs noch mal auf ganz einfachem Wege versucht, nur um überhaupt mal vorwärts zu kommen.


[DllImport("ftd2xx.dll",SetLastError=true)]
		public static extern ulong FT_Open(int deviceNumber,[MarshalAs(UnmanagedType.LPArray)] Int32[] nSize);

		public void Open()
		{
			Int32[] len=new Int32[1];
			status = FT_Open(0, len);
			Console.WriteLine(status.ToString());
		}

Keine Fehler mehr, dafür aber nen DllNotFoundException. Jemand ne Idee?

gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

F
29 Beiträge seit 2005
vor 18 Jahren

Hallo,

fehlt vielleicht noch ein Verweis auf die DLL?

Gruss Frank

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Ein Verweis geht hier nicht, da es keine COM Dll ist.

gruss dschmoegner

*EDIT*

Die Dll musste im Systemverzeichnis liegen. Der Programmpfad hat alleine nicht ausgereicht.

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

Original von dschmoegner

//leider weiss ich nicht wieviel Speicher FT_HANDLE
//benötigt für[/csharp]

Anscheinend übersteigt das Ganze doch meinen momentanen Kenntnisstand.
Dennoch Danke

Wie hast Du die Struktur FT_HANDLE deklariert ?

FT_HANDLE f=new FT_HANDLE();
Type t=f.GetType();
.
.
.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Guten Morgen,

so ist FT_HANDLE in dem Headerfile zur DLL deklariert. Leider liegen meine letzten Programmiererfahrungen mit C++ etwas zurück. PVOID kommt mir zwars bekannt vor, aber ich weiss nicht mehr in welchem Zusammenhang.

Original von dschmoegner

  
typedef PVOID	FT_HANDLE;  
typedef ULONG	FT_STATUS;  
  

Gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

ich wollte eigentlich wissen wie du dieses Teil in C# deklariert hast

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Ups sorry,

da ich Handles bisher nur als ulong oder uint Werte kenne hatte ich an so etwas gedacht, schliesslich ist es ja nur ein Zeiger auf die momentane Verbindung. Oder wäre es besser FT_Handle als eigene Klasse zu implementieren? Dann hätte ich zumindestens eine eigene Instanz, wobei das ja auch mit einer Membervariablen lösbar wäre.

gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

Idealerweise als struc oder als Klasse implementieren

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Okay, dann werde ich mich mal weiter dahinterklemmen und schauen was dabei rumkommt.

Schon mal vielen Dank für die Hilfe.

gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007