Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
C++ Dll in C# Compact Framework nutzen
maume
myCSharp.de - Member

Avatar #avatar-2464.gif


Dabei seit:
Beiträge: 11
Herkunft: nähe Bonn

Themenstarter:

C++ Dll in C# Compact Framework nutzen

beantworten | zitieren | melden

Hallo,

ich habe eine in C++ geschriebene Dll, die ich im C# Compact Framework nutzen will.
Grundsätzlich ist das auch kein Problem, da dies über DLLImport geht.

Allerdings ist der Aufbau einer Funkion der DLL wie folgt:

int Anmelden(char *ergebnis, char *bmp);

Wie kann ich nun einen Pointer auf die Variable übergeben?

Gruß
maume
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Leider sind C-Signaturen nicht aussagekräftig genug um deine Frage ohne weitere Informationen (in/out) zu beantworten.

Wenn aber dein Parameter ein vorallokiertes Char-Array ist, welches von der Funktion gefüllt werden soll (zumindest ergebnis scheint so ein out-Kandidat zu sein) dann musst du StringBuilder verwenden. Also ein StringBuilder-Objekt mit der passenden Länge erzeugen und reinstecken.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von svenson am .
private Nachricht | Beiträge des Benutzers
maume
myCSharp.de - Member

Avatar #avatar-2464.gif


Dabei seit:
Beiträge: 11
Herkunft: nähe Bonn

Themenstarter:

beantworten | zitieren | melden

Ich habe nun folgenden Code:

[DllImport("terminal.dll")]
unsafe private static extern int Anmelden(ref StringBuilder ergebnis, ref StringBuilder bmp);

StringBuilder ergebnis = new StringBuilder(2);
StringBuilder bmp = new StringBuilder(257);

i = Anmelden(ref ergebnis, ref bmp);

Wenn ich das nun ausführe geht auch alles gut, bis zum Aufruf von Anmelden.
Da bekomme ich als Exception
Can't find PInvoke DLL 'terminal.dll'.
Die DLL liegt im gleichen Verzeichnis, wie die ausgeführte EXE.

Könnt ihr mir damit auch helfen?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von maume am .
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Die Fehlermeldung tritt auch auf, wenn nicht genug Speicher zur Verfügung steht um die DLL zu laden.
private Nachricht | Beiträge des Benutzers
maume
myCSharp.de - Member

Avatar #avatar-2464.gif


Dabei seit:
Beiträge: 11
Herkunft: nähe Bonn

Themenstarter:

beantworten | zitieren | melden

Kann es evtl. auch damit zu tun haben, dass die DLL ursprünglich für Win32 geschrieben ist?
Dann müsste ich den Entwickler noch mal ansprechen, ob ich die DLL auch für WinCe haben kann.
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Default-Marshalling auf CE ist Unicode. char* ist aber ANSI. Also CharSet=CharSet.Ansi im DLLImportAttribute.
private Nachricht | Beiträge des Benutzers
maume
myCSharp.de - Member

Avatar #avatar-2464.gif


Dabei seit:
Beiträge: 11
Herkunft: nähe Bonn

Themenstarter:

beantworten | zitieren | melden

Ich kann im DLLImport aber nur Unicode oder Auto einstellen.

Wenn ich das ganze nun so mache

[DllImport("terminal.dll", CharSet = CharSet.Auto,SetLastError= true, EntryPoint = "Anmelden")]
unsafe private static extern int Anmelden(ref StringBuilder ergebnis, ref StringBuilder bmp);

kommt leider immer noch die PInvoke Exception.
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8775
Herkunft: Berlin

beantworten | zitieren | melden

Stimmt. Dann empfehle ich: Benutze die OpenNETCF-Lib. Da gibts die Klasse Marshal2 und dort eine Funktion PtrToStringAnsi().

Dann musst du anstelle des StringBuilders den Parameter IntPtr nutzen. Mittels Marshal.AllocGobalH Speicher reservieren und dann via IntPtr übergeben. Nach unmanaged Aufruf mit PtrToStringAnsi() den Inhalt des Speichers in einen String kopieren. Dann den Speicher mit MArshal.FreeGlobalH freigeben.

Leider wäre es natürlich die unmanaged Funktion in Unicode zu ändern (wchar*).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von svenson am .
private Nachricht | Beiträge des Benutzers