Laden...

Probleme mit eingebundener Dll und BSTR* (.NET Compact Framework)

Erstellt von TheWizzard vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.914 Views
T
TheWizzard Themenstarter:in
5 Beiträge seit 2005
vor 18 Jahren
Probleme mit eingebundener Dll und BSTR* (.NET Compact Framework)

Hallo,

Ich habe ein Problem beim einbinden einer in Visual eMbedded C++ geschriebenen Dll.
In dieser Dll gibt es eine Funktion, die einen BSTR* als Argument nimmt. In diesen BSTR* wird dann ein String geschrieben. Wenn ich nun jedoch einen IntPtr übergebe und diesen dann mit Marshal.PtrToStringUni konvertiere und ihn in einer MessageBox anzeigen lasse, dann kommt nur Müll raus.

C++ Code


int test(BSTR *test)
...
test = (BSTR*)"test";
...

C# Code


[DllImport("test.dll", EntryPoint="test")]
public static extern int test(ref IntPtr test);

weiter unten dann


IntPtr t = new IntPtr(0);
int ret = test(ref t);
MessageBox.Show(Marshal.PtrToStringUni(t));

In der MessageBox wird nun nur wirres zeug angezeigt. Erst dachte ich es hätte irgendwas mit Unicode/ASCII etc zu tun, aber egal wie ich den String auch änder, die MessageBox zeigt immer dasselbe an.

Vielen Dank im Vorraus
TheWizzard

D
95 Beiträge seit 2005
vor 18 Jahren

Hi Wizzard,
und warum definierst du nicht


[DllImport("test.dll", EntryPoint="test")]
public static extern int test( string test); 

?
Ansonsten gibt es schon viele Threads zu übergabe an DLL Funktionen.
Detlef

S
8.746 Beiträge seit 2005
vor 18 Jahren

BStrings sind zwar Unicode, allerdings mit Längenpräfix. Mit PtrToStringUni() kommst du dan nicht weiter. Du müßtest PtrToStringBStr() verwenden, aber das wird vom CF nicht unterstützt.

Theoretisch gäbe es da noch das MarshalAs-Attribute "BStr", das wird sogar vom CF unterstützt, aber die Klasse MarshalAS selbst nicht (selten bescheuerte Doku!).

Im CF 1.0 ist nichts eingebaut mit dem du Bstr wandeln kannst (daher auch keine COM-Anbindung). Ab 2.0 gibt es sowohl PtrToStringBStr() als auch MarshalAs.BStr.

Alternativ kann du eine Freeware-Bib verwenden:

http://www.inthehand.com/CategoryView,category,Downloads.aspx

Hier gibt es ComMarshal.PtrToStringBSTR()

T
TheWizzard Themenstarter:in
5 Beiträge seit 2005
vor 18 Jahren

@deti61: Hab ich auch schon probiert, selbes Problem.

@svenson: Hab mich auch schon geärgert das es da MarshalAs nicht gibt. Werd mir mal die Bibliothek angucken.

*EDIT*
Hab grad gesehen, dass die Bibliothek nur für nicht-kommerzielle Zwecke kostenlos ist. Kann man nicht manuell in einem unsafe Block die kovertierung machen? Ich werd mal gucken, ob Google dazu was ausspuckt.

Danke

TheWizzard

T
TheWizzard Themenstarter:in
5 Beiträge seit 2005
vor 18 Jahren

Hmmm
Mit .net 2.0 scheint das ja alles wunderbar zu funktionieren. Wie stabil ist denn die beta 2? Irgendwelche erfahrungen? Und ist eigentlich bekannt, wann die finale .Net 2.0 version rauskommt?

MfG

TheWizzard

S
8.746 Beiträge seit 2005
vor 18 Jahren

Hier mal ein Stück Code aus einer Newsgroup:

How about replacing it with the following code:

int nLen = SysStringLen(ptr) ' Needs to be pinvoked
Dim buffer() as Byte = new Byte(nLen * 2) ' or whatever VB syntax is
Marshal.Copy(ptr, buffer, 0, nLen * 2)
str = Encoding.Unicode.GetString(buffer)

I suggest that you also carefully check the nLen value there to see that
it's reasonable

SysStringLen() muss du via DLLImport einbinden. Die fehlende Null-Terminierung verkraftet GetString() offenbar wegen der bekannten Länge des Byte-Arrays.

T
TheWizzard Themenstarter:in
5 Beiträge seit 2005
vor 18 Jahren

🙂 werde ich gleich mal ausprobieren

T
TheWizzard Themenstarter:in
5 Beiträge seit 2005
vor 18 Jahren

SysStringLen wird zwar einwandfrei aufgerufen, gibt aber eine riesige Zahl zurück, und daher gibt es dann eine OutOfMemoryException. Hab schon bei google gesucht, konnte aber nichts dazu finden. Vielleicht sollte ich wirklich auf .Net 2.0 migrieren, allerdings stört mich irgendwie der beta status.