Edit
Attach
Printable
topic end
<!-- * Set TOPICTITLE = #define private public - Claus Brod on software (13 Dec 2004) * Set ALLOWTOPICCHANGE = Main.ClausBrod --> <style type="text/css"> pre {background-color:#ffeecc;} </style> %STARTINCLUDE% <a name="20041213"></a> ---+++ [[BlogOnSoftware20041213][.NET tut net...]] (13. Dezember 2004) Auf meine alten Tage befasse ich mich doch tatsächlich auch noch mit solchen Dingen wie Microsoft .NET. Wenn man mir das während meines Studiums und meiner hyperaktiven [[http://www.clausbrod.de/atari/atari.html][Atari-Zeit]] prophezeit hätte... Nun denn. Kommt mir neulich so ein häßlicher kleiner Käfer entgegen. Und das kam so: Wenn man Werte vom Typ =bool= aus "managed code" in "unmanaged code" per Marshaling überträgt, geht das in so richtig großen Stil schief. Der "managed code" (in C++) stellt einen einfachen Aufruf zur Verfügung mit einem Rückgabewert vom Typ =bool=. Vereinfachter Beispielcode: <pre> public __gc __interface IBool { bool Foo(void); }; public __gc class Booltest : public IBool { public: Booltest() {} bool Foo(void) { return false; } }; </pre> Diesen Code übersetzt man in ein Assembly, und daraus produziert man mittels =regasm= eine Typenbibliothek (tlb-Datei). Gleichzeitig registriert =regasm= das Assembly; und hinterher werfen wir das Assembly in den Schlund des GAC. Auszug aus der erzeugten Typenbibliothek: <pre> interface IBool : IDispatch { [id(0x60020000)] HRESULT Foo([out, retval] unsigned char* pRetVal); }; </pre> Man beachte, daß der Typ des Rückgabewerts vom =bool= nach =unsigned char= abgeändert wurde. Soweit keine Überraschung, denn [[http://blogs.msdn.com/adam_nathan/][Nathan]] erwähnt in seiner COM-Interop-Bibel, daß der Marshaling-Typ für Werte vom Typ =bool= eben =UnmanagedType::U1= ist - also =unsigned char=. So richtig übel wird es aber, wenn ich nun =Foo()= aus einem COM-Client zu rufen versuche. Der COM-Client erzeugt sich einen "smart pointer" vom Typ =IBoolPtr= und ruft dann =Foo()=: <pre> bool ret = pBool->Foo(); </pre> Nach diesem Aufruf ist allerdings der Stack beschädigt. Läft man im Einzelschritt durch den Code, merkt man, daß der COM-Client denkt, der Rückgabewert sei ein Byte gross; daher legt er auch nur ein Byte auf dem Stack für die Ergebnisvariable =ret= an. Der Marshaling-Code allerdings schreibt munter _vier_ Bytes! Das gleiche passiert, wenn man im "managed code" das Attribut =[MarshalAs(<nop>UnmanagedType::U1)]= ausdrücklich anwendet. Microsoft beschreibt im [[http://support.microsoft.com/default.aspx?scid=kb;en-us;823071][Knowledge-Base-Artikel 823071]] einen möglicherweise verwandten Fehler beim Marshaling von <tt>bool</tt>-Werten, allerdings hilft der vorgeschlagene Hotfix in meinem Fall nicht. Ändere ich den Marshaling-Typ auf =U2=, wird's noch lustiger: Dann überschreibt der Marshaler zwar keinen Speicher mehr, räumt dafür aber den Stackpointer nach dem Aufruf nicht mehr auf! Hat jemand Ideen? (Siehe auch http://groups.google.de/groups?hl=de&lr=&threadm=10gd95ifu6uoe9a%40corp.supernews.com.) PS: Einige Zeit später hat uns Microsoft bestätigt, daß das in der Tat ein Fehler in .NET 1.1 war. .NET 2.0 macht's nun richtig. --- %STOPINCLUDE% %COMMENT{type="below" nonotify="on"}% ---
to top
End of topic
Skip to action links
|
Back to top
Edit
|
Attach image or document
|
Printable version
|
Raw text
|
Refresh
|
More topic actions
Revisions: | r1.1
|
Total page history
|
Backlinks
You are here:
Blog
>
BlogOnSoftware20041213
r1.1 - 28 Jan 2007 - 22:25 -
ClausBrod
to top
Blog
This site
2017
:
12
-
11
-
10
2016
:
10
-
7
-
3
2015
:
11
-
10
-
9
-
4
-
1
2014
:
5
2013
:
9
-
8
-
7
-
6
-
5
2012
:
2
-
10
2011
:
1
-
8
-
9
-
10
-
12
2010
:
11
-
10
-
9
-
4
2009
:
11
-
9
-
8
-
7
-
6
-
5
-
4
-
3
2008
:
5
-
4
-
3
-
1
2007:
12
-
8
-
7
-
6
-
5
-
4
-
3
-
1
2006:
4
-
3
-
2
-
1
2005:
12
-
6
-
5
-
4
2004:
12
-
11
-
10
C++
CoCreate Modeling
COM & .NET
Java
Mac
Lisp
OpenSource
Scripting
Windows
Stuff
Changes
Index
Search
Maintenance
Impressum
Datenschutzerklärung
Home
Webs
Atari
Blog
Claus
CoCreateModeling
Klassentreffen
Main
Sandbox
Sommelier
TWiki
Xplm
Jump:
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback