Laden...

Unmanaged dll in c# einbinden und void** als Parameter einer Methode erstellen

Erstellt von wdarius vor 12 Jahren Letzter Beitrag vor 12 Jahren 4.611 Views
W
wdarius Themenstarter:in
4 Beiträge seit 2011
vor 12 Jahren
Unmanaged dll in c# einbinden und void** als Parameter einer Methode erstellen

Hallo,

ich habe ein Problem beim benutzen einer unmanaged dll.
Das Einbinden funktioniert ohne Probleme.

Beim benutzen einer der Methoden der dll muss ich einen void** Parameter übergeben z.B. X. Das mache ich mit IntPtr X und leite den Pointer mit ref weiter an die Methode.

Anschließend muss ich eine weitere Methode aufrufen, die den X Pointer möchte jedoch dieses mal als void*. Wie kann so etwas in c# anstellen?

Habe schon viel gegoogelt aber bislang nichts passendes gefunden.

Vielen Dank im voraus.
Darius

S
401 Beiträge seit 2008
vor 12 Jahren

Hallo,

Das Einbinden funktioniert ohne Probleme.

Das soll wohl heißen, dass alles ohne Probleme funktioniert mit der Ausnahme des void-Zeigers.

Beim benutzen einer der Methoden der dll muss ich einen void** Parameter übergeben z.B. X. Das mache ich mit IntPtr X und leite den Pointer mit ref weiter an die Methode.

Type* := Zeiger auf ein Objekt, zur Zeit ist ein Zeiger ein Integer-Wert der Größe 32/64bit (je nach Betriebssystem)
Type** := hier handelt es sich ebenfalls um einen Zeiger. Jedoch mit der Besonderheit, dass der Zeiger auf einen weiteren Zeiger zeigt. Der zweite Zeiger zeigt auf ein Objekt.

void* := ein Zeiger auf ein Objekt. Der Type des Objekts ist unbekannt.
string* := ein Zeiger auf ein Objekt. Der Type des Objekts ist ein string.
void ** := Zeiger -> Zeiger -> unbekanntes Objekt

void-Zeiger sind auch in C# erlaubt und vorhanden.
Zeigertypen (C#-Programmierhandbuch)

Anschließend muss ich eine weitere Methode aufrufen, die den X Pointer möchte jedoch dieses mal als void*. Wie kann so etwas in c# anstellen?

Wie? Das kann ich so nicht beantworten. Hierzu benötige ich jedenfalls ein wenig Code.

edit: Vielleicht hilft folgendes

__declspec( dllexport )
long write(FILEHANDLE hFilehandle, void* pBuffer, const long Size);

[DllImport("mydll.dll",CallingConvention=CallingConvention.C
decl)]
internal static extern
int
write ( IntPtr hFileHandle,
       [In, MarshalAs( UnmanagedType.LPArray )] byte [] buf, 
       int size);
W
wdarius Themenstarter:in
4 Beiträge seit 2011
vor 12 Jahren

Zitat von wdarius:
Das Einbinden funktioniert ohne Probleme.

Das soll wohl heißen, dass alles ohne Probleme funktioniert mit der Ausnahme des void-Zeigers.

Genau.

Zitat von wdarius:
Anschließend muss ich eine weitere Methode aufrufen, die den X Pointer möchte jedoch dieses mal als void*. Wie kann so etwas in c# anstellen?

Wie? Das kann ich so nicht beantworten. Hierzu benötige ich jedenfalls ein wenig Code.

Die Methode getList der dll:
void getList(void** list)
Diese Methode trägt in den out Parameter list ein wo ich meine Liste im Speicher finde. Pointer-> Pointer -> Liste

Die Methode useList der dll
void useList(void* list, ...)
Diese Methode soll list aus der ersten Methode benutzen um wiederum einen weiteren Parameter zu berechnen. Pointer -> Liste

Dieses mal soll der Parameter aber halt nicht void** sein sondern void*, also entsprechend der Pointer auf die List.

Mein Problem hierbei ist, dass ich einen void* pointer per IntPtr erstellen kann. Aber wie mache ich einen void** Pointer mit IntPtr.

S
248 Beiträge seit 2008
vor 12 Jahren

Hallo,

definiere void** entweder als "ref IntPtr" wenn der Parameter in/out ist oder als "out IntPtr" wenn er nur out ist.

Als Beispiel:

bool getList(out IntPtr address, ...);
void useList(IntPtr address, ...);

....
IntPtr address = InPtr.Zero;
if (getList(out address, ...))
  useList(address);
...

Grüße

spooky

156 Beiträge seit 2010
vor 12 Jahren

void getList(void** list)
void useList(void* list, ...)

wenn mich meine C Kenntnisse jetzt nicht ganz täuschen


void* meineliste;
// ..
getList(&meineliste);
// ..
useList(meineliste);

beim Ersten mal will die DLL nur den Pointer (bzw. die Adresse) haben wo Dein Pointer für die Liste liegt ... um dort die Adresse der Liste rein zuschreiben ... wie das genau in C# aussieht weis ich nicht ... ich greifen in den Fällen (wenn es dazu kommt) lieber auf C++/CLI zurück

hand, mogel

W
wdarius Themenstarter:in
4 Beiträge seit 2011
vor 12 Jahren

Danke für die Antworten. Ich werde es so bald wie möglich testen.

S
401 Beiträge seit 2008
vor 12 Jahren

Die Methode getList der dll:
void getList(void** list)
Diese Methode trägt in den out Parameter list ein wo ich meine Liste im Speicher finde. Pointer-> Pointer -> Liste

Die Methode useList der dll
void useList(void* list, ...)
Diese Methode soll list aus der ersten Methode benutzen um wiederum einen weiteren Parameter zu berechnen. Pointer -> Liste

erstmal.
void ** ist auch nur ein Pointer. Kann also auch mit IntPtr behandelt werden. Aber das ist nicht dein Problem.

#! C
// header.h

// gibt einen Pointer auf die entsprechende Stelle zurück
void* getList ();
// Vorsicht, ist C++. Eine Pointerreferenz als Parameter.
// call by reference
void getList (void *& ref);

// Warnung
// call by value
void getList (void * ref);

// *.c
static void *ptr;
static void value;

void* getList () { return ptr;}
void* getList() { return &value;}

void getList (void *& ref)
{
  ref = ptr;
}

void getList (void *& ref)
{
  ref = &value;
}

Denn Unterschied zwischen Call by Value und Call by Reference kannst du selber nachlesen 😉

W
wdarius Themenstarter:in
4 Beiträge seit 2011
vor 12 Jahren

Hab es jetzt hinbekommen.
Es war einfacher als ich dachte.
Ich habe für den void ** Typ IntPtr genommen.
Anschließend den selben Pointer für den void* Typ.
Anscheinend werden die Pointer direkt richtig gemarsheld.

Ref hab ich in diesem Fall nur für void** genommen da dort die dll den Pointer im ummanaged Bereich selbst setzt. Halt ein out.