Dll-Funktionen mit Pointern in C# aufrufen
-
HI
bin total verzweifelt weil alles was ich probiere nicht funktioniert.
Habe von Extern eine Dll mit Beschreibung. Diese Dll möcht ich in C# einbinden und Funktionen daraus aufrufen. Die Funktion die ich haben möcht ist folgerdermaßen angegeben.int CONV(int mode, int width, int height, word *b12, byte *b8, void *lut);
Einbinden tu ich das ganze so:
[DllImport("pcocnv.dll")] unsafe public static extern int CONV(int mode, int width, int height, void* alt, byte* neu, void* lut);
und aufrufen so:
unsafe private void dll_aufruf() { void* snapshot = pic_snap; byte* snap = null; int mode = 0, width = 640, height = 480; void *bwlut; ... CONV(mode, width, height, snapshot, snap, bwlut); }
pic_snap ist ein Pointer, bwlut wird zugewiesen ist in diesem Fall nicht relevant. Problem ist, dass ich in snap einen Wert zurückbekommen sollte, tu ich aber nicht. Die Eingabeparameter sind richtig nur in snap steht immer null drin. Wieso? Ist da irgendwo noch ein Fehler drin?
Noch was andres Wie kann ich den Inhalt des Pointers in ne Variable schreiben, bevorzugt wär ein String.
Danke
-
schau dir mal diese keywords in c# an: ref und out
-
Danke
Mit denen hab ich auch schon rumprobiert aber bisher leider erfolglos
-
Hi.
Xqgene schrieb:
schau dir mal diese keywords in c# an: ref und out
Das geht nur, wenn die Parameter der Funktion mit __gc-Attribut versehen sind :
Quotenmausi schrieb:
int CONV(int mode, int width, int height, word __gc *b12, byte __gc *b8, void __gc *lut);
@Quotenmausi
Wie sind bei dir die Datentypen word & byte definiert ? Wenn du mitQuotenmausi schrieb:
[DllImport("pcocnv.dll")] unsafe public static extern int CONV(int mode, int width, int height, void* alt, byte* neu, void* lut);
importierst, stellst du im 4. Parameter von word* auf void* um, das kann
Probleme machen. Bei mir gilt für WORD :typedef unsigned short WORD;
Ich weiss nicht, ob es was bringt, aber vielleicht solltest du mal mit
ushort* probieren.Unter Umständen hilft es auch, wenn man beim DllImport-Attribut den
Funktionsnamen explizit angibt. Das hab ich schon mal gesehen, aber
noch nie ausprobiert.mfg BlueShift
-
BlueShift schrieb:
Hi.
Das geht nur, wenn die Parameter der Funktion mit __gc-Attribut versehen sind :So sind sie leider nicht deklariert.
BlueShift schrieb:
Bei mir gilt für WORD :
C/C++ Code:
typedef unsigned short WORD;stimmt hab ich auch gerade gesehen. Habs mit ushort ausprobiert auch kein Ergebnis aber Danke für den Hinweis.
Wie schauts denn eigentlich mit Konvertierung von Pointern in Variablen oder umgekehrt aus?
-
Quotenmausi schrieb:
Wie schauts denn eigentlich mit Konvertierung von Pointern in Variablen oder umgekehrt aus?
Konvertierung von Pointern in Variablen ? Das ist gefährlich !
in C++ geht das bekanntlich mit reinterpret_cast.int val = reinterpret_cast<int>(/* Dein Zeiger */0) int *ptr = reinterpret_cast<int*>(92);
Wie es in C# geht, weiss ich eigentlich nicht ! Es müsste aber ähnlich gehen.
Oder meinst du etwaunsafe { int buf, val, *ptr; ptr = &buf; ptr = 92; val = *ptr; }
oder sonst eine Art von "Konvertierung" ?
Ach ja, sind in der Dll auch Klassen ?
mfg BlueShift
-
Danke genau solche zuweisungen hab ich gemeint. Pointer sind nicht so meine Stärke und ich dacht mir ich komm denen mit C# aus, aber leider hab ich mich da getäuscht
BlueShift schrieb:
Ach ja, sind in der Dll auch Klassen ?
nein Klassen sind so weit ich weiss keine drin, zumindest wird in der Beschreibung dazu nix erwähnt. Warum?
-
Ich denke ich weiss mittlerweile wo das Problem liegt, dass ich keinen Wert in meinen Pointer bekomme. Ich Denke, dass sich der Wert byte* neu nicht erneuert. Dies liegt daran, dass ich den Pointer in C# als null deklariere und er, da er nicht by ref geladen wird, sich nicht aktualiesert.
ref Funktioniert nicht, da die Pointer der dll nicht mit __gc gekennzeichnet ist.
Gibt es in C# ne Möglichkeit Pointer zu aktualisieren? Oder eine andere Möglichkeit auf die Dll zuzugreifen?
Eine Möglichkeit müsst sein das ganze über eine C++-Wrapperklasse zu machen.
-
Hallo.
Du hast recht, ich hab gar noch nicht an null gedacht !
Das Problem ist, dass dein Zeiger auf 0 zeigt. Du kannst ihm also
keinen Wert zuweisen. Dieser Code wirft eine System::NullReferenceException :int main() { int __nogc *ptr, strg; *ptr = System::Environment::TickCount; }
Folgender Code funktioniert dagegen einwandfrei.
int main() { int __nogc *ptr, strg; ptr = &strg; *ptr = System::Environment::TickCount; }
In deiner C++-Dll ist aber System::NullReferenceException nicht bekannt,
weshalb keine Exception geworfen wird. Es wird einfach weitergefahren.
Initialisiere den Zeiger, dann geht es vielleicht. Eine Wrapper Dll in
Managed C++ kann ich nur empfehlen, dass ist am sichersten !
mfg BlueShift