<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET Coding</title>
        <link>http://geekswithblogs.net/dirksblog/category/2805.aspx</link>
        <description>.NET Coding</description>
        <language>de-DE</language>
        <copyright>Dirk Eisenberg</copyright>
        <managingEditor>dirk.eisenberg@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>using System.Security.Principal</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2008/12/19/128068.aspx</link>
            <description>&lt;p&gt;Mit &lt;a title="" href="http://de.wikipedia.org/wiki/.NET" target="_blank"&gt;.NET&lt;/a&gt; 2.0 wurde der namespace System.Security.Principal um ein paar Klassen zur Verwaltung von Accounts erweitert. Hierbei handelt es sich um die gute alte Abstraktion von &lt;font face="Courier New"&gt;LookupAccountSid&lt;/font&gt; und &lt;font face="Courier New"&gt;LookupAccountName&lt;/font&gt;. Diese Funktionen finden sich in den neuen Klassen &lt;font face="Courier New"&gt;NTAccount &lt;/font&gt;und &lt;font face="Courier New"&gt;SecurityIndentifier&lt;/font&gt; wieder. Beide Klassen basieren auf einer Basis-Klasse mit dem Namen &lt;font face="Courier New"&gt;IdentityReference&lt;/font&gt;. Folgendes Beispiel zeigt wie man aus einem User-Account die entsprechende SID erzeugt. Diese Vorgang ist natürlich auch umgedreht möglich:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;NTAccount user = new NTAccount("Administrator");&lt;br /&gt;
SecurityIdentifie sid = null;&lt;br /&gt;
if ( user.IsValidTargetType(typeof(SecurityIdentifier)))&lt;br /&gt;
  sid = (SecurityIdentifier)user.Translate(typeof(SecurityIdentifier));&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128068"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=128068" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/128068.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2008/12/19/128068.aspx</guid>
            <pubDate>Sat, 20 Dec 2008 04:42:51 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/128068.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2008/12/19/128068.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/128068.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/128068.aspx</trackback:ping>
        </item>
        <item>
            <title>.NET Unmanaged API - Teil 1</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2006/05/07/77514.aspx</link>
            <description>puh, schon wieder sind einige Wochen vergangen und ich habe nix zu diesem Blog beigetragen. Diese Woche hatte ich dann ein Erlebnis was mich zum Bloggen nötigt. Wie der Titel schon verrät, soll es um einen Teil des &lt;a title="" href="http://de.wikipedia.org/wiki/.NET" target="_blank"&gt;.NET&lt;/a&gt; Frameworks gehen, der nicht unbedingt gut dokumentiert ist und den Name "Unmanaged API" trägt.  Die Unmanaged &lt;a title="" href="http://de.wikipedia.org/wiki/.NET" target="_blank"&gt;.NET&lt;/a&gt; Api stellt ein Set von COM-Interfaces zur Verfügung um auf die Meta-Daten eines &lt;a title="" href="http://de.wikipedia.org/wiki/.NET" target="_blank"&gt;.NET&lt;/a&gt;-Assemblies aus native Code heraus zuzugreifen. Eine Populärer Anwendung dieser API ist Visual Studio 2005 selbst. Viele Funktionen die sich sonst in System.Reflection befinden, sind ebenfalls über diese Schnittstelle erreichbar. Schauen wir uns ein Beispiel an, das prüft ob die gegebene Datei ein gültiges .NET Assembly ist:

&lt;pre&gt;
HRESULT hr = CoCreateInstance(	CLSID_CorMetaDataDispenser, 0, CLSCTX_INPROC_SERVER, IID_IMetaDataDispenser, 						(LPVOID*)&amp;pIMetaDataDispenser);
if (SUCCEEDED(hr))
{
 mdAssembly asmToken;
 hr = pIMetaDataDispenser-&gt;OpenScope(	L"MyAssemblyImage", ofRead, IID_IMetaDataAssemblyImport, (LPUNKNOWN*)&amp;pIMetaDataAssemblyImport); 
 hr = pIMetaDataAssemblyImport-&gt;GetAssemblyFromScope(&amp;asmToken);
 
 bool bIsAssembly = false;
 if (SUCCEEDED(hr))
  bIsAssembly = true;  
}
&lt;/pre&gt;

Eigentlich spricht der Code für sich, zuerst benötigen wir eine Instanz des MetaDataDispenser wodurch wir Zugriff auf alle Metadaten-Tabellen erhalten. Jetzt ist es möglich auf die verschiedenen Bereiche zuzugreifen. In diesem Beispiel auf die Meta-Daten in denen die Referenzen auf andere Assemblies zu finden sind. Um zu erkennen ob es ein gültiges Assembly ist, wird der Seiteneffekt genutzt das jedes Assembly diese Tabelle besitzt und das Öffnen dieses Scopes nur bei native-Binaries nicht funktioniert.

&lt;b&gt;Randbemerkung:&lt;/b&gt;
Die Unmanaged API steht nur auf Computern zur Verfügung auf denen auch ein .NET-Framework installiert ist. Viele der unterstützten Funktionen werden ab .NET 1.0 unterstützt. Die benötigte include Datei "cor.h" findet sich in den Headern des .NET-Frameworks und muss eingebunden werden. Dabei wird indirekt die Datei specstrings.h angezogen. Diese steht erst in einem der letzten SDKs zur Verfügung (ich nutze das Windows 2003 Server SP1 SDK).
&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77514"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77514" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/77514.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2006/05/07/77514.aspx</guid>
            <pubDate>Mon, 08 May 2006 03:28:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/77514.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2006/05/07/77514.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/77514.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/77514.aspx</trackback:ping>
        </item>
        <item>
            <title>[Update] Der managed P/Invoke Mediator</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71475.aspx</link>
            <description>&lt;P&gt;Wenn sich nach dem &lt;A href="http://geekswithblogs.net/dirksblog/archive/2006/03/05/71475.aspx"&gt;letzten Artikel&lt;/A&gt; vielleicht jemand fragt warum funktioniert das, sollte einen kurzen Blick auf die verschiedenen Bestandteile von Platform Invoke werfen. Daraus wird deutlich warum in einem Assembly DllImport-Verweise auf nicht existierende Dll vorhanden sein k&amp;#246;nnen und wann das &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt;-Framework wie auf die native DLL zugreift.&lt;/P&gt;
&lt;P&gt;Check this out: &lt;A href="http://msdn2.microsoft.com/en-us/library/h50dxzwx.aspx"&gt;http://msdn2.microsoft.com/en-us/library/h50dxzwx.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;There are three parts to a &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; Compact Framework platform invoke:&lt;/EM&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;EM&gt;At design-time, the developer provides a description of the unmanaged function to call. This includes the module name (DLL file), entry point name, and calling convention. &lt;/EM&gt;&lt;/P&gt;
&lt;LI&gt;
&lt;P&gt;&lt;EM&gt;At just-in-time (JIT) compile time, the common language runtime extracts this information from the metadata, locates the DLL containing the function, loads the DLL into memory and retrieves the address of the function. If the module or function is not found, the common language runtime throw a &lt;?XML:NAMESPACE PREFIX = MSHelp NS = "http://msdn.microsoft.com/mshelp" /&gt;&lt;MSHelp:link tabIndex=0 keywords="T:System.MissingMethodException"&gt;MissingMethodException&lt;/MSHelp:link&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;LI&gt;
&lt;P&gt;&lt;EM&gt;At run time, the common language runtime marshals the parameters from managed format to unmanaged format before the unmanaged function is called. The common language runtime &lt;/EM&gt;&lt;/P&gt;
&lt;LI&gt;
&lt;P&gt;&lt;EM&gt;determines how to marshal each parameter based upon the managed declaration of the method.&lt;/EM&gt;&lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Weiterhin sie auf das &lt;A href="http://msdn2.microsoft.com/en-us/library/ms229660.aspx"&gt;HowTo - Get the Device Platform&lt;/A&gt;&amp;nbsp;verwiesen. Dadurch l&amp;#228;sst sich der Platform Runtime Check auf sichere Beine stellen.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=71475"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=71475" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/71475.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71475.aspx</guid>
            <pubDate>Mon, 06 Mar 2006 02:21:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/71475.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71475.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/71475.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/71475.aspx</trackback:ping>
        </item>
        <item>
            <title>Der managed P/Invoke Mediator</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71471.aspx</link>
            <description>&lt;P&gt;Nach dem &lt;A href="http://mcblogs.craalse.de/sku?title=64_bit_windows_teil_9&amp;amp;more=1&amp;amp;c=1&amp;amp;tb=1&amp;amp;pb=1"&gt;letzten Blog&lt;/A&gt; meines &lt;A href="http://www.stefan-kuhr.de/"&gt;gleichgesinnten Kollegens&lt;/A&gt;&amp;nbsp;hat mich das Thema P/Invoke nicht mehr&amp;nbsp;los gelassen. Ich ging nur mit einer etwas&amp;nbsp;anderen Einstellung in das Thema. Mein Programmche soll nicht die File Redirection von&amp;nbsp;%systemroot%\system32 nutzen. Nein ich will keine Forwarder-Library in&amp;nbsp;das System32-Directory kopieren. Zustimmung erh&amp;#228;lt aber trotzdem das Mediator.Prinzip. Dieser&amp;nbsp;Mediator bestimmt welche native DLL geladen wird. Im Fall von 64Bit Windows w&amp;#228;re das die 64Bit-Dll, im Fall von 32Bit Windows die 32Bit-Dll und im Falle von Windows CE und dem Compact Framework eine andere.&lt;/P&gt;
&lt;P&gt;Mein Ziel ist aber die gesamte Distribution meiner Software in %ProgramFiles%\MySoftware zu handeln und eine foo.dll f&amp;#252;r 32Bit Windows, eine foo64.dll f&amp;#252;r 64Bit Windows und eine fooCe.dll f&amp;#252;r Windows CE zu halten.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Versuch Nummer 1:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Bendenkt man das Attribute in &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; nur Klasse abgeleitet von System.Attribute sind, liegt die Idee nah das DllImportAttribute erneut abzuleiten und im Property-Handling f&amp;#252;r den DllName die Logik f&amp;#252;r die Namens-Nomenklatur zu Implementieren. Leider macht das kleine aber wichtige Schl&amp;#252;sselwort &lt;FONT face="Courier New"&gt;&lt;EM&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfsealed.asp"&gt;sealed&lt;/A&gt;&lt;/EM&gt;&lt;/FONT&gt; einen Strich duch die Rechnung. Damit sorgt das &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; Framework das keine weitere Ableitung von dieser Klasse m&amp;#246;glich ist. Der n&amp;#228;chste Versuch war irgendeine Art Logik hinter den DllName zu h&amp;#228;ngen. Leider unterst&amp;#252;tzt auch hier das &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; Framework nur konstante Parameter-Werte in Attributen. Also auf zu neuen Ufern.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Versuch Nummer 2:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Verfolgt man das Mediator-Konzept weiter, will aber keine eigene Forwarder-Dll schreiben, ist vielleicht folgendes Konzept hilfreich. F&amp;#252;r jede unterst&amp;#252;tzte Plattform wird eine DllImportHelper-Klasse implementiert. Diese kapselt lediglich das Marshaling und die DllImport-Anweisung. Um den Zugriff auf die richtige Helper-Klasse zu realisierien wird eine Schnittstelle zur Verf&amp;#252;gung gestellt. DieseDllImport-Klasse orchestriert den Zugriff auf die korrekte Helper-Klasse. Je nach aktueller Plattform wird die entsprechende Methode aus der korrekter DllImport-Helper-Klasse aufgerufen. &lt;/P&gt;
&lt;P&gt;Vorteile:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Das Mediator-Konzept wurde beibehalten und das Assembly kann einfach um weitere Plattformen erweitert werden. Baut man das Konzept aus,&amp;nbsp;so ist&amp;nbsp;eine Erweiterung f&amp;#252;r neue Platformen in reinem Managed-Code ohne Ver&amp;#228;nderung des aufrufenden Codes m&amp;#246;glich. 
&lt;LI&gt;Die Verwaltung einer extra Forwarder-Dll entf&amp;#228;llt. 
&lt;LI&gt;Die Applikation muss keine Libraries in %systemroot%\system32 ablegen.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Nachteil:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Die Bestimmung der aktuellen Platform kostet extra Zeit und verlangsamt den Sprung in den native Code nochmals. 
&lt;LI&gt;Es muss f&amp;#252;r jede Platform eine extra Klasse im Assembly gehalten werden aber kein zweites Assembly.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Ein einfaches Beispiel ist &lt;A href="http://www.dirk-eisenberg.de/files/PInvokeTest.cs"&gt;hier&lt;/A&gt; hinterlegt. Dieses Beispiel soll nur illustrieren wie das prinzipielle Vorgehen ist und wurde nicht f&amp;#252;r den produktiven Einsatz vorgesehen.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;64Bit Runtime Check:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Wie findet der geneigte Entwickler in C# heraus ob sich der Prozess gerade als 64Bit bzw. 32Bit-Prozess l&amp;#228;uft. Leider ist festzustellen das Microsoft in seinem Environment-Objekt keine passable L&amp;#246;sung f&amp;#252;r das Problem vorr&amp;#228;tig hat. Folgende L&amp;#246;sung stammt aus &lt;A href="http://blogs.msdn.com/joshwil/archive/2005/08/10/450198.aspx"&gt;diesem Blog&lt;/A&gt;&amp;nbsp;und &lt;A href="http://blogs.msdn.com/kstanton/archive/2004/04/20/116923.aspx"&gt;hier&lt;/A&gt; findet man wie es nicht gemacht werden sollte. Unter C# ist ein int-Datentyp immer 32Bit lang, egal ob 64Bit-Prozess der 32Bit-Prozess aber der IntPtr ist je nach Prozess-Art 32Bit oder 64Bit lang. &lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;bool bIs64Bit = (sizeof(IntPtr) == 8 )&lt;/FONT&gt;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=71471"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=71471" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/71471.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71471.aspx</guid>
            <pubDate>Mon, 06 Mar 2006 01:06:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/71471.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2006/03/05/71471.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/71471.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/71471.aspx</trackback:ping>
        </item>
        <item>
            <title>Ein neues Buch für mich</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/12/04/62086.aspx</link>
            <description>&lt;P&gt;Als ich diese Woche wiedermal an meinem Schreibtisch vorbei gekommen bin (nat&amp;#252;rlich hatte ich meine Tasse dabei) fand sich &amp;#252;berraschend dieses Buch:&lt;/P&gt;
&lt;P align=center&gt;&lt;IMG src="/images/geekswithblogs_net/dirksblog/2811/o_ilassembler.gif"&gt;&lt;/P&gt;
&lt;P&gt;Jetzt beginne ich ganz begeistert in die Tiefen der IL einzusteigen und werde an dieser Stelle ab und an davon berichten. Das ist wohl die einzige Art f&amp;#252;r mich mit &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; richtig warm zu werden ;-)&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=62086"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=62086" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/62086.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/12/04/62086.aspx</guid>
            <pubDate>Sun, 04 Dec 2005 18:03:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/62086.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/12/04/62086.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/62086.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/62086.aspx</trackback:ping>
        </item>
        <item>
            <title>Interior Pointer und GCHandles</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/11/11/59826.aspx</link>
            <description>&lt;P&gt;Wow, jetzt ist schon wieder ein ganzer Monat vergangen, ohne das ich einen Blog-Beitrag fertig bekommen habe. Ich schiebe das mal auf den Umstand das der Tag nur 24 Stunden hat und besser 48 haben sollte. Aber nun zum Thema dieses Beitrags.&lt;/P&gt;
&lt;P&gt;Mich qu&amp;#228;lte in letzter Zeit eine Frage: Kann ich aus native C++ Code in ein Managed Assembly springen und wenn ja wie &amp;#252;berlistet man den Garbage Collector&amp;nbsp;damit man nicht mit &amp;#252;ng&amp;#252;ltigen Pointer nach dem n&amp;#228;chsten Cycle dasteht. Betrachten wir folgendes typische Pattern einer beliebigen Runtime wie so auch unter Windows selbst vorkommt. Um am geselligen Leben dieser Runtime teilhaben zu d&amp;#252;rfen, wird uns die Implementierung einer DLL mit&amp;nbsp;folgenden Einsprungspunkten vorgegeben (und das auch noch mit &lt;FONT face="Courier New"&gt;__stdcall&lt;/FONT&gt;):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face="Courier New"&gt;Init( LPVOID* lpUserDefinedData ); &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Courier New"&gt;Event1(&amp;nbsp;LPVOID lpUserDefinedData ); &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Courier New"&gt;Event2( LPVOID lpUserDefinedData ); &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT face="Courier New"&gt;UnInit( LPVOID lpUserDefinedData );&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Wir haben also 4 Funktionen als Interface, eine Init, eine UnInit und zwei Aktionen. Der Entwickler der Runtime hat uns die M&amp;#246;glichkeit gegeben benutzerspezifische Daten durchzuschleifen um keine globalen Objekte in unserem Modul halten zu m&amp;#252;ssen, super. Jetzt stellen sich zwei Fragen:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Ist es m&amp;#246;glich das gesamte Modul in &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt;&amp;nbsp;zu implementieren ohne die Runtime selbst zu ver&amp;#228;ndern? 
&lt;LI&gt;Wie schafft man es eine Referenz auf eine &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt;-Klasse &amp;#252;ber den UserData-Parameter durchzuschleifen ohne das der GC bei der Heap-Reorganisation den Pointer zerst&amp;#246;rt ?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Frage 1 beantwortet sich recht einfach, &lt;A title="" href="http://de.wikipedia.org/wiki/.NET" target=_blank&gt;.NET&lt;/A&gt; bietet die M&amp;#246;glichkeit native Funktions-Exporte zu erzeugen. Dadurch wird ein Eintrag in der EAT des PE-Files erzeugt, der direkt in den&amp;nbsp;.NET-Code springt (Das ist mal einen eigene Beitrag wert). Hier ist es nun m&amp;#246;glich mit gemanagten Objekten zu arbeiten. Etwas versteckt findet sich auch die M&amp;#246;glichkeit Exporte zus&amp;#228;tzlich &amp;#252;ber ein Def-File zu steuern und nicht &amp;#252;ber die &lt;FONT face="Courier New"&gt;__cdeclspec(dllexport)&lt;/FONT&gt;-Anweisung.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="/images/geekswithblogs_net/dirksblog/2811/o_fxNetBridge_Def.JPG"&gt;&lt;/P&gt;
&lt;P&gt;Wie k&amp;#246;nnten jetzt also die Implementierung unsere Funktionen aussehen:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;unsigned int __stdcall Init( void** lpUserData )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; return 0;&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Damit k&amp;#246;nnen wir uns der zweiten Fragen widmen: "Wie bekomme ich jetzt eine Referenz auf ein .NET-Objekt durchgeschleift?" Den ersten Gedanken verschwenden wir an den pin-Mechnismus der doch funktionieren sollte. Folgender Code k&amp;#246;nnte das Problem l&amp;#246;sen:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;unsigned int __stdcall Init( void** lpUserData )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if ( lpUserData )&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CMyManagedObject^ refOb =&amp;nbsp;gcnew CMyManagedObject();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pin_ptr&lt;VOID&gt; pInteriorPointer = &amp;amp;refOb;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *lpUserData = pInteriorPointer;&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; return 0;&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Hierzu muss man wissen das gepinnte Pointer nur so lange g&amp;#252;ltig sind, bis das entsprechende StackFrame verlassen wird. Dadurch w&amp;#228;re unser Pointer schon bald nicht mehr sicher und der GC w&amp;#252;rde beim n&amp;#228;chsten Cycle unter Umst&amp;#228;nden den Heap ver&amp;#228;ndern.&amp;nbsp;Wie also weitermachen? Mit GC-Handles steht uns eine M&amp;#246;glichkeit zur Verf&amp;#252;gung einen eindeutigen und positionsunabh&amp;#228;ngigen Verweis auf ein managed Objekt zu erzeugen. Als besonders n&amp;#252;tzlich stellt sich die Tatsache heraus, das dieser Verweis in Form eines Integer Wertes daher kommt. Also auf gehts:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;if ( lpUserData )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; CMyManagedObject^ refOb = gcnew CMyManagedObject();&lt;BR&gt;&amp;nbsp;&amp;nbsp;GCHandle gch = GCHandle::Alloc( refOb );&lt;BR&gt;&amp;nbsp; IntPtr iRef = gch.ToIntPtr( gch );&lt;BR&gt;&amp;nbsp; *lpUserData = (void*)(int)iRef;&lt;BR&gt;&amp;nbsp;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Schon fast fertig. Der Integer kann jetzt jederzeit in das Objekt zur&amp;#252;ck verwandelt werden, solange nicht GCHandle::Free aufgerufen wird. Diese Methode muss aber aufgerufen werden, sobald dieses Handle nicht mehr ben&amp;#246;tigt wird. Jetzt kommt uns aber ein entscheidender Vorteil zu Hilfe. Im Gegensatz zu &lt;FONT face="Courier New"&gt;pin_ptr&lt;/FONT&gt;&lt;VOID&gt; darf ein GCHandle-Objekt Member einer Klasse sein. Dadurch ist es m&amp;#246;glich die ganze Schnittstelle in einer .NET-Klasse zu kapseln:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;class ref CMyManagedObject&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntPtr GetFixedId()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;(!m_gch.IsAllocated())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_gch = GCHandle::Alloc( this );&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return GCHandle::ToIntPtr( m_gch );&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void ReleaseHandle()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_gch.Free();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static CMyManagedObject^ GetTarget( IntPtr ip )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GCHandle gcHandle = GCHandle::FromIntPtr( ip );&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (CMyManagedObject^)gcHandle.Target();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp; protected:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GCHandle m_gch;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Jetzt habe wir die Klasse, nur wie sieht unser Implementierung aus:&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;unsigned int __stdcall Init( void** lpUserData )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if ( lpUserData )&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CMyManagedObject^ refOb =&amp;nbsp;gcnew CMyManagedObject();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntPtr ip = refOb-&amp;gt;GetFixedId();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *lpUserData = (void*)(int)ip;&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; return 0;&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;unsigned int __stdcall UnInit( void* lpUserData )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if ( lpUserData )&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CMyManagedObject^ refOb =&amp;nbsp;CMyManagedObject::GetTarget( (IntPtr)lpUserData )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; refOb-&amp;gt;ReleaseHandle();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; return 0;&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Ruft das Framework jetzt die Einsprungspunkte auf, haben wir jederzeit die M&amp;#246;glichkeit auf das .NET-Objekt zu verweisen und den gesamten Umfang des .NET-Frameworks zu nutzen. Durch diese Technik ist es M&amp;#246;glich bestehende Frameworks um Erweiterungen zu bereichern, die mit Hilfe des .NET-Frameworks entwickelt wurden.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=59826"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=59826" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/59826.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/11/11/59826.aspx</guid>
            <pubDate>Sat, 12 Nov 2005 02:26:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/59826.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/11/11/59826.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/59826.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/59826.aspx</trackback:ping>
        </item>
        <item>
            <title>Property Handling leicht gemacht</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/09/25/54928.aspx</link>
            <description>&lt;P&gt;Da es heute regnet und auch der &lt;A href="http://www.sixflags.com/parks/greatamerica"&gt;SixFlag-Park &lt;/A&gt;hier in Chicago geschlossen hat, habe ich mich f&amp;#252;r meinen &lt;A href="http://geekswithblogs.net/dirksblog/gallery/image/1360.aspx"&gt;Laptop&lt;/A&gt; entschieden um weiter an meinem .Net-Binding einer unter meinen Kollegen nicht ganz unbekannten Library zu basteln. Dabei habe ich f&amp;#252;r C++ Entwickler eine weitere, gewinnbringende Verbesserung durch die neue C++/CLI angetroffen. &lt;/P&gt;
&lt;P&gt;Folgendes C#-Pattern ist wohl jedem bekannt:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public string Name&lt;BR&gt;{&lt;BR&gt;    get&lt;BR&gt;    {&lt;BR&gt;        return m_name;&lt;BR&gt;    }&lt;BR&gt;    set&lt;BR&gt;    {&lt;BR&gt;        m_name = value;&lt;BR&gt;    }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Genau es ist die Implementierung einer Eigenschaft die &amp;#252;ber die Methode set geschrieben und mit get gelesen werden kann. Dabei braucht der Benutzer dieser Klasse nicht set und get selbst aufrufen, nein das Framework steuert den Aufruf &amp;#252;ber die Zugriffsrichtung. Das finde ich ist schonmal eine n&amp;#252;tzliche Sache nur wie hat das managed C++ gel&amp;#246;st ?&lt;/P&gt;&lt;PRE class=code&gt;__property String* get_Name()
{
    return m_value;
}
__property String* set_Name(String* value)
{
    m_value = value;
}
&lt;/PRE&gt;
&lt;P&gt;Es gab nur das keyword __property, welches eine Methode als setter bzw. getter einer Property markiert, wodurch so mancher w&amp;#228;hrend der Maintenance verwirrt werden konnte. Das wurde mit der neuen C++/CLI ge&amp;#228;ndert. Jetzt sind folgende Konstrukte m&amp;#246;glich.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;property String^ Name&lt;BR&gt;{&lt;BR&gt;    public:&lt;BR&gt;     String^ get()&lt;BR&gt;     {&lt;BR&gt;        return m_value;&lt;BR&gt;     }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;    private:&lt;BR&gt;     void set(String^ value)&lt;BR&gt;     {&lt;BR&gt;        m_value = value;&lt;BR&gt;     }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Das Beste aus meiner Sicht ist die unterschiedliche Markierung des Codes als public oder private. So kann gesteuert werde ob der zugriff auf das Klassen-Member nur lesend, nur schreibend oder unbeschr&amp;#228;nkt erlaubt ist. &lt;/P&gt;
&lt;P&gt;Weiterhin kann man nat&amp;#252;rlich Threading-Issues in diesen Methoden elegant implementieren und der Nutzer kommt nicht herum durch diesen Code zu laufen, weil ja der Compiler f&amp;#252;r den Sprung in diese Methoden sorgt.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;CFoo^ foo = gcnew CFoo();&lt;BR&gt;foo-&gt;Name = "Hello World";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt; Das war bei unmanaged C++ anders. Ich hoffe es kommt beim Thema Multi-Threading keiner auf die platte Idee zu meinen, wenn die Variable static ist, wird der Zugriff darauf durch das Framework sowieso serialisiert. Wer dieser Meinung ist, sollte nochmals die Definition von static nachlesen (und zwar in alle Variation, managed und unmanged).&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=54928"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=54928" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/54928.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/09/25/54928.aspx</guid>
            <pubDate>Sun, 25 Sep 2005 20:51:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/54928.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/09/25/54928.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/54928.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/54928.aspx</trackback:ping>
        </item>
        <item>
            <title>C++/CLI, C4980, __box, __pin</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/09/06/52753.aspx</link>
            <description>&lt;P&gt;Eigentlich wollte ich doch nur &amp;#252;ber eine etwas &amp;#228;ltere Win32-Dll ein nettes .NET-Interface bauen. Es sollte Klassen geben zur Verwaltung der Resourcen und Zugriffe usw. Nat&amp;#252;rlich sollte alles gleich mit dem neusten vom neusten funktionieren und somit habe ich mich f&amp;#252;r Visual Studio Beta 2 mit dem .NET-Framework 2 entschieden. Nachdem die erste H&amp;#252;rden &amp;#252;berwunden waren und ich mich etwas mit dem GC besch&amp;#228;ftigt hatte, erschien die nette Warnung &lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;C4980: '__gc' : use of this keyword requires /clr:oldSyntax command line option &lt;/FONT&gt;&lt;FONT face="Times New Roman" size=3&gt;Ich ahnte nicht gutes. Nach einigem Suche habe ich kapiert das im .NET-Framework 2 einiges an der Integration von C++ ge&amp;#228;ndert wurde (oh h&amp;#228;tte ich vielleicht am Anfang erw&amp;#228;hnen sollen, ja ich nutze dazu C++ und nicht C#). Dankbar war ich dann f&amp;#252;r folgenden Link&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/VS05Cplus.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/VS05Cplus.asp&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Ich versuche mal mit zwei Ver&amp;#228;nderungen zu starten, die aus meiner Sicht von gro&amp;#223;em Interesse sind:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Nutzung der C++ Pointer-Darstellung zum Zugriff auf Objekte die der Speicherverwaltung des GC unterliegen&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;In vorherigen Versionen gab es das keyword &lt;FONT face="Courier New"&gt;__gc&lt;/FONT&gt; um deutlich zu machen, das es sich um eine Klasse unter der Aufsicht der GC handelt oder das die Speicherallokation auf dem managed Heap stattfindet. Das Ergebnis war augenscheinlich ein C++-Pointer. Das Problem dabei stellt die automatische Verschiebung der Objekte durch den GC dar. Weiterhin ist es unter Umst&amp;#228;nden einer Funktion/Methode nicht mehr m&amp;#246;glich anzusehen ob diese nun einen managed-Pointer erwartet oder nicht(zumindest nicht sofort). Auch folgender Code war mit unter nicht eindeutig:&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;CMyClass* pClass  = new CMyClass();&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;Ist die Klasse durch das keyword __gc als managed markiert kommt dabei was ganz anderes raus als ein nativer C++-Pointer. Da ist folgender Code schon klarer:&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;CMyClass __gc* pClass = new CMyClass();&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;Im .NET Framework 2 hat man dem ein Ende gesetzt und einen nen Operator sowie ein neues Schl&amp;#252;sselwort f&amp;#252;r Klassen  eingef&amp;#252;hrt. Der Operator '^' markiert jetzt eine Referenz auf ein Objekt im managed Heap des GC. Das Schl&amp;#252;sseltwort 'ref' markiert eine Klasse als managed. Zus&amp;#228;tzlich wurde der &amp;#252;berladene new-Operator verworfen und daf&amp;#252;r der gcnew-Operator eingef&amp;#252;hrt  (Betrifft wieder nur C++). Jetzt ist eine klare Trennung zwischen Allokationen auf dem managed Heap und dem CRT-Heap m&amp;#246;glich.&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;ref class CMyClass&lt;BR&gt;{&lt;BR&gt;   public:&lt;BR&gt;     CMyClass() {};&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;CMyClass^ refObjectt = gcnew CMyClass();&lt;/FONT&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Implizites Boxing ersetzt __box&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Boxing wird ben&amp;#246;tigt um einen Br&amp;#252;cke zwischen den Wert-Typen und richtigen Objekte zu schaffen. Wenn man sich einen int-Wert-Typ mal genau betrachtet ist er gar kein richtiges Objekte, obwohl doch alles in der CLR von System::Object abgeleitet sein sollte. Ein int-Wert stellt einfach nur Daten auf dem Stack dar. Erst durch das Boxing des int-Wertes wird ein richtig Objekt draus.(An dieser Stelle sei auf den oben genannten Link verwiesen). Also was musste man fr&amp;#252;her als C++-Entwickler machen:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;int value_i = 5;&lt;BR&gt;System::Object* pObject = __box(value_i);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Das ist aber garnicht C++-Like also wurde hier aus dem expliziten Boxing mit Hilfe des neu eingef&amp;#252;hrten Referenz-Operators ein implizites Boxing:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;int value_i = 5;&lt;BR&gt;System::Object^ refObject = value_i;&lt;BR&gt;int value_i2 = *(int^)refObject;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Wie bekommt man jetzt aber eine vern&amp;#252;nftige Initialisierung einer Referenz hin ? Ganz einfach, man nutzt das neu eingef&amp;#252;hrte keyword &lt;FONT face="Courier New"&gt;nullptr&lt;/FONT&gt;. Auch das ist wieder eine Ver&amp;#228;nderung die nur C++ betrifft. C# begn&amp;#252;gt sich weiterhin mit &lt;FONT face="Courier New"&gt;null&lt;/FONT&gt;.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;System::Object^ refObject = nullptr;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wie geht es weiter ?&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Ich werde in einem der n&amp;#228;chsten Posts die Reihe mit folgenden Themen weiterf&amp;#252;hren:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Das IDispose-Interface&lt;/LI&gt;
&lt;LI&gt;Property-Handling&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Wer darauf nicht warten will, kann do oben aufgef&amp;#252;hrten Artikel lesen. &lt;BR&gt;Kommentare, Erweiterungen oder Korrekturen sind herzlich willkommen.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=52753"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=52753" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/52753.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/09/06/52753.aspx</guid>
            <pubDate>Tue, 06 Sep 2005 11:22:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/52753.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/09/06/52753.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/52753.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/52753.aspx</trackback:ping>
        </item>
        <item>
            <title>WinFS is back on track [Update]</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51679.aspx</link>
            <description>&lt;P&gt;Auch auf Channel 9 hat sich viel zu diesem Thema getan.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://channel9.msdn.com/showpost.aspx?postid=106356"&gt;http://channel9.msdn.com/showpost.aspx?postid=106356&lt;/A&gt;&lt;/P&gt;
&lt;P&gt; &lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=51679"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=51679" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/51679.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51679.aspx</guid>
            <pubDate>Wed, 31 Aug 2005 09:55:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/51679.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51679.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/51679.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/51679.aspx</trackback:ping>
        </item>
        <item>
            <title>WinFS is back on track</title>
            <link>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51677.aspx</link>
            <description>&lt;P&gt;Es geschehen noch Zeichen und Wunder, Microsoft hat heute die Beta 1 des aus Windows Vista verschwundenen WinFS released. Alle MSDN-Kunden bzw. PDC-Teilnehmern steht die Beta zum Download zur Verf&amp;#252;gung. Was kommt nun mit?&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Nat&amp;#252;rlich WinFS als System selbst inklusiven einer Shell-NameSpace-Extension und eine Win32 Integration. Damit ist ein WinFS-Storage kompatibel zur Win32-File-IO-Api. 
&lt;LI&gt;Die .NET-Api f&amp;#252;r WinFs inklusive Dokumentation 
&lt;LI&gt;Einige Tools, die aber als unsupported gelten&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Hier soll noch kurz erw&amp;#228;hnt werden welche Tools mitkommen und was damit gemacht werden kann (oder auch nicht). Alle Tools befinden sich nach der Installation im &lt;EM&gt;Unsupported&lt;/EM&gt;-Ordner.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;StoreSpy&lt;/STRONG&gt; bietet die M&amp;#246;glichkeit alle in einem Storage liegende Daten etwas genauer anzuschauen. Es k&amp;#246;nnen alle bekannten Attribute ausgelesen werden und Beziehungen zwischen einzelnen Items visualisiert werden. Das Tool soll auch einen Synchronisationsfunktion mit Outlook haben, hat bei mir aber noch nie getan. &lt;/P&gt;
&lt;P&gt;Der &lt;STRONG&gt;WinFSTypeBrowser&lt;/STRONG&gt; ist ein n&amp;#252;tzliches Tool um alle bekannten WinFS-Typen anzuschauen. Dabei kann der gesamte .NET-Namensraum bestaunt werden. Sehr hilfreich wenn man mit WinFS startet (so wie ich).&lt;/P&gt;
&lt;P&gt;Hat man dann mal Lust auf mehr bekommen bietet sich &lt;STRONG&gt;OPather&lt;/STRONG&gt; an, damit ist es m&amp;#246;glich OPath-Anfragen an WinFS zu stellen ohne gro&amp;#223;en Programmieraufwand. Das Tool generiert auch gleich den ben&amp;#246;tigten C#-Code f&amp;#252;r die erzeugte Abfrage.&lt;/P&gt;
&lt;P&gt;Zuletzt sei noch &lt;STRONG&gt;Rave&lt;/STRONG&gt; erw&amp;#228;hnt. Dieses Tool basiert auf WinFS-Sync und bietet die M&amp;#246;glichkeit Daten zwischen zwei WinFS-Ordnern zu synchronisieren. &lt;/P&gt;
&lt;P&gt;Als &lt;A href="http://geekswithblogs.net/dirksblog/articles/51670.aspx"&gt;Artikel&lt;/A&gt; versteckt findet sich ein kleines Tool was die ersten Schritte mit der WinFS-Api zeigt. Weiter Samples und Ausf&amp;#252;hrungen zu diesem Thema folgen bald.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=51677"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=51677" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/dirksblog/aggbug/51677.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dirk Eisenberg</dc:creator>
            <guid>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51677.aspx</guid>
            <pubDate>Wed, 31 Aug 2005 09:36:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/dirksblog/comments/51677.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/dirksblog/archive/2005/08/31/51677.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/dirksblog/comments/commentRss/51677.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/dirksblog/services/trackbacks/51677.aspx</trackback:ping>
        </item>
    </channel>
</rss>