Laden...

DLL Funktionen importieren

Erstellt von Masquerader vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.142 Views
M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren
DLL Funktionen importieren

Hallo,

hab ein kleines Problem... Ich soll eine Auswertesoftware für einen Prüfstand programmieren. Dazu benötige ich die Anbindung an die Hardware. Für die D/A-Wandlerkarte gibt es Treiber (lib und dll) für C. Dazu auch Anleitungen für die API. Bloß irgendwie funzt das nicht...

Also die Funktion ist laut LIB wiefolgt beschrieben:

int I_PCI3001_InitCompiler (unsigned char b_CompilerDefine)

Die Funktionen befinden sich in einer DLL names ADDI_W32.DLL.

Wäre schön wenn irgendjemand posten könnte wie ich diese Funktion importieren kann.

Vielen Dank

Masque

PS: Bitte nicht zu kompliziert machen - hab nicht sonderlich viel Ahnung 😮/

X
2.051 Beiträge seit 2004
vor 18 Jahren

F1 --> DllImport
oder Suche --> DllImport

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

OK, erstmal vielen Dank.

Meinen ersten Aufruf mach ich mit:


[DllImport("PCI3001.DLL", EntryPoint = "i_PCI3001_InitCompiler")] 
static public extern int i_PCI3001_InitCompiler(byte b_CompilerDefine);

Das funktioniert auch richtig gut. Jetz hab ich ein neues Problem. Und zwar heißt die nächste Funktion laut LIB:


int i_PCI3001_CheckAndGetPCISlotNumber (byte* pb_SlotNumberArray);

Wenn ich das analog zu oben versuche, bringt er immer:

Zeiger können nur in einem nicht sicheren Kontext verwendet werden

Was kann man da tun??

Masque

S
8.746 Beiträge seit 2005
vor 18 Jahren

IntPtr verwenden. Ist die "verwaltete" Entsprechung eines Pointers.

U
91 Beiträge seit 2004
vor 18 Jahren

Hallo Masque,

habe gerade vor einem ähnlichen Problem gestanden. Ich habe das gelöst indem ich in der DLL statt dem byte * einen IntPtr verwendet habe und habe mir mit der Marshal-Klasse wie in den guten alten Zeiten Speicher allokiert, dann meine Daten reinkopiert und fertig war die Laube. Dann jedoch nicht vergessen den Speicher wieder frei zu geben, ebenfalls wie in den guten alten Zeiten. Falls deine DLL die Daten verändert solltest du vor der Freigabe nicht vergessen sie wieder in ein Array zu kopieren.


Gruß
Uwe

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Erstmal danke für die schnellen Antworten, aber das is mir alles etwas zu hoch... Wie muss ich das jetzt machen? Hab's probiert mit:


[DllImport("PCI3001.DLL", EntryPoint = "i_PCI3001_CheckAndGetPCISlotNumber")]
static public extern int i_PCI3001_CheckAndGetPCISlotNumber(IntPtr(byte pb_SlotNumberArray));

Aber das klappt nicht wirklich... Wäre schön, wenn sich mal jemand die Zeit nehmen könnte und ein Stück Quellcode schreiben könnte.

Vielen Dank

Masque

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Ok, hab's nochmal probiert...

Mit:


[DllImport("PCI3001.DLL", EntryPoint = "i_PCI3001_CheckAndGetPCISlotNumber")]
static public extern int i_PCI3001_CheckAndGetPCISlotNumber(IntPtr pb_SlotNumberArray);

funzt zumindest der Programmstart, wenn ich aber versuche drauf zuzugreifen mittels:


int 	i_ReturnValue;
byte []	b_SlotNumberArray = new byte[10];

i_ReturnValue = i_PCI3001_CheckAndGetPCISlotNumber(b_SlotNumberArray);

Es kommt aber immer der Fehler:

kann nicht von 'byte[]' zu 'System.IntPtr' konvertiert werden

Vielen Dank schonmal

Masque

S
8.746 Beiträge seit 2005
vor 18 Jahren
  1. Marshal.AllocHGlobal()
  2. Marshal.Copy() (IntPtr von AllocHGlobal übergeben)
  3. DLL-Aufruf
  4. Marshal.FreeHGlobal()
U
91 Beiträge seit 2004
vor 18 Jahren

Hallo Masque,

ich gehe jetzt einfach mal davon aus dein Zeiger zeigt normalerweise auf ein 8 Byte großes Array. Dan müßte dein Code ungefähr so aussehen:


[DllImport("PCI3001.DLL", EntryPoint = "i_PCI3001_CheckAndGetPCISlotNumber";)]
static public extern int i_PCI3001_CheckAndGetPCISlotNumber(IntPtr pb_SlotNumberArray);


byte[] abSlotNumber = new byte[8];

IntPtr pSlotNumber = Marshal.AllocHGlobal(8);
// abSlotNumber wenn nötig mit Daten füllen

Marshal.Copy(abSlotNumber,0,pSlotNumber, 8); // Daten aus Array in Speicher
int nResult = i_PCI3001_CheckAndGetPCISlotNumber(pSlotNumber);
// wenn nötig wieder zurückkopieren
Marshal.Copy(pSlotNumber, abSlotNumber,0,8);

Marshal.FreeHGlobal(pSlotNumber);


Gruß
Uwe

M
Masquerader Themenstarter:in
31 Beiträge seit 2005
vor 18 Jahren

Vielen vielen Dank,

hat prima funktioniert.

Masque