Thomas Wölfers Baustatik-Blog

Thomas Wölfers Baustatik Blog

Die nächsten Termine


Die Termine für die beiden nächsten Anwenderseminare (in München und Oberhausen) stehen fest - beide sind im März. Details und Links zu den Anmeldeformularen gibt es hier.

Auch der Termin für den nächsten Stammtisch in München steht fest: Der ist am Dienstag den 24.3. ab 19:30, wie immer im Pauls in der Maxvorstadt. Ich bitte um eine kurze Mail (an tw@die.de ), falls Sie kommen wollen - je frühzeitiger, umso besser :-)


Wie man herausfindet, ob die eigene C# Anwendung als x86 oder x64 läuft


Sofern man die "Platform Target" eines C# Projectes nicht explizit setzt, dann wird die Anwendung zur Laufzeit auf einer x86 Platform eine x86 Anwendung sein, und auf einer x64 Platform eine x64 Anwendung: Das ist praktisch, wenn man es nur mit managed Code zu tun hat, denn man bekommt die 64bit Variante quasi geschenkt.

Wenn man aber auch nativen Code hat muss man - je nachdem wie man die Anwendung baut - in Abhängigkeit der aktuellen Platform unterschiedliche DLLs laden. Also zum Beispiel die Calc32.dll für x86 und die Calc64.dll unter x64. Wie findet man aber nun heraus, ob man sich in einer x86 oder in einer x64 Umgebung befindet? MSDN läst sich zu diesem Thema nicht besonders aus; zumindest konnte ich nichts finden.

Allerdings liegt das vielleicht daran, das die Lösung mehr als einfach ist: Alles was man tun muss ist die Größe eines IntPtr anzusehen. Hat der Zeiger eine Größe von 8 Byte, dann befindet man sich in einer x64 Umgebung. (8 Byte mal 8 Bits => 64 bit).

Manche Dinge sind wirklich deutlich einfacher als man meinen sollte... :-)


Ausdruck von Navigationspunkten: Woher kommen die Überschriften?


Der Ausdruck von Navigationspunkten - bzw. der Ausdruck von deren Überschriften - ist ein wenig kompliziert. Um genau zu sein: Er funktioniert in der aktuellen nicht wirklich richtig.... was zwar bisher nicht wirklich viele Anwender gestört hat, es wird sich aber im nächsten Updaten trotzdem ändern - und hoffentlich besser werden :-)

Es bleibt aber dabei, das es vielleicht nicht auf den ersten Blick einsichtig ist, woher die Beschriftungen eigentlich kommen. Darum will ich hier einmal versuchen, das zu erklären. Beim Ausdruck eines Navigationspunktes gibt es bis zu zwei Überschriften. Die eine davon ist die Überschrift die angibt, welches Ergebnis gerade angezeigt wird. An dieser Überschrift kann man nichts umstellen und man kann sie auch nicht abschalten: Enthält der Navigationspunkt eine Ergebnisdarstellung, dann wird die Überschrift angezeigt. Enthält er keine, dann gibt es die Überschrift auch nicht.

Oberhalb der Ergebnisbeschreibung gibt es eine (optionale) weitere Überschrift. Diese zweite Überschrift kann man pro Navigationspunkt in der Ausdrucksteuerung ein- und ausschalten: Sie wird also entweder mit ausgegeben oder nicht. Wenn Sie ausgegeben wird, dann zeigt sie einen von zwei möglichen Texten an: Hat man im Navigationspunkt einen Kommentar eingegeben, dann wird der Kommentartext ausgegeben. Hat man keinen Kommentartext eingegeben, dann wird als Überschrift der Text "Abb.: " und der Name des Navigationspunktes ausgegeben.


Gestern in München: Vortrag von Oliver Scheer zu Silverlight 2


Etwa 4 Stunden rund um Silverlight 2: Wer es nicht weiss - Silverlight 2 ist im wesentlichen WPF im Browser (Safari, Firefox, IE), für verschiedene Systeme (OS/X, Windows, Linux [in Vorbereitung]) und auch auf verschiedenen Geräten (auch Telefone ohne Window Mobile).

Der Vortrag war nett und unterhaltsam, brachte aber nichts wirklich neues: Wer sich "von selbst" auf dem laufenden hält wird nicht viel gelernt haben - für alle anderen gab es eine schöne Rundum-Ansicht der zu Silverlight gehörenden Infrastruktur und deren Möglichkeiten. Besonders gefiel mir eines von Olivers Lieblingsausdrücken: Das Web 2.0 konforme Rechteck - mit runden Ecken... :-)

Jedenfalls kann ich den Vortrag jedem empfehlen, der sich auf die schnelle einen Einblick in Silverlight verschaffen will - es gibt, so glaube ich - auch noch ein paar Termine.


Von Managed C++ nach C++/CLI


In VS 2008 ist die Syntax von Managed C++ bereits deprecated - höchste Zeit, auf C++/CLI umzustellen. Die ausführliche Referenz dazu befindet sich hier: C++/CLI Migration Primer - ich denke für die meinsten Fälle kommt man aber mit einer Kurzfassung aus:

Zeiger
Ein Vorteil von C++/CLI über die "managed Extensions" ist die Tatsache, das viele Dinge viel schöner hingeschrieben werden können - und auch besser zu erkennen sind. Das geht mit Zeigern los: Ein Zeiger in den Managed Heap wird nun mit ^ statt mit * markiert:  Faselwurst^ pWurst zeigt also auf eine Instanz vom Typ Faselwurst, die sich im Managed Heap befindet.

Typen
Bisher wurde eine Klasse als gc__ class TypeName definiert - jetzt heist es statt dessen "ref class TypeName".

Arrays
Bisher war ein Array aus Instanzen im Managed Heap ein gc__[] variablenName TypeName. Das heist nun array<Type>(Dimension). Ein Zeiger auf so ein Array ist also ein array<Type>^ varName.

Properties
Die neue Syntax für Properties ähnelt doch sehr stark der von C#:
property int Zahl
{
    int get()
    {
    }
    void set( int v)
    {
        member = v;
    }
}

Interface-Implementierungen
Implementiert eine Klasse ein Interface, dann müssen die implementierten Member nun "virtual" sein.

Die bisher aufgeführten Änderungen sind weiter nicht dramatisch, sonfern man weiss, wie man die Dinge hinschreiben muss: Wirklich falsch machen kann man eigentlich nichts, denn der Compiler bewirft einen schon mit passenden Fehlermeldungen. Das ist in einem besonderen Fall aber nicht so, und dabei geht es um die Destruktoren. Das Problem: Der Compiler meckert hier nichts an, denn man kann zwar weiterhin die "alte" Destruktor-Notation verwenden: Dummerweise hat sich aber deren Semantik verändert. Macht man die Sache aber falsch und reagiert nicht auf die Semantik-Änderung, gibt es Speicher-Lecks im nativen Heap. Das passiert, wenn man eine C++/CLI Instanz hat, die als Member Zeiger auf den nativen Heap hat. Die Instanz an sich wird bei Notwendigkeit brav vom GC eingesammelt und verworfen. Dabei wird der normale Destruktor aber nicht unbedingt aufgerufen - zumindest nicht, wenn man nicht weiter tätig wird. Resultat: Leck. Das war früher nicht so - daher muss man auf diese Problematik gesondert achten. Die ausführliche Referenz zum Thema findet sich hier.

Im Wesentlichen läuft es aber auf folgendes hinaus: Damit die Destruktoren der C++/CLI Typen "richtig" aufgerufen werden, braucht man immer ein Konstrukt dieser Art:

ref class MyType
{
private:
   int* pNative;

// ..... weitere implementierungs-Details in deren Zuge pNative auf allozierten nativen Speicher zeigt.

public:
   // Das wird im IL ein Dispose()
   ~MyType() { Destruct(); }
   // Das wird im IL ein Finalizer.
   !MyType() { Destruct(); }

private:
   void Destruct()
   {
      if( pNative != 0)
      {
           delete pNative;
           pNative = 0;
      }
   }
};

Nur als Hinweis: Das ist so nicht unbedingt die effizienteste Methode, die Sache zu regeln - daher ist es u.U. ganz sinnvoll den oben verlinkten Artikel doch einmal genauer zu studieren.