More C++ Idioms

August 2nd, 2010

Hallo,

wer sich für C++ interessiert und seinen Horizont erweitern will sollte mal auf die Seite “More C++ Idioms” auf wikibooks.org anschauen.

Dabei kann man nicht nur bekannte C++ Pattern wie Empty Base Class Optimization oder Copy-and-swap wiederholen sondern sich auch interessante neue Ideen aneignen, wie z.B. Safe bool.

Aber Achtung: im Gegensatz zu der Angabe auf der Seite würde ich die Anforderungen an die Leser nicht als “intermediate” sondern als “advanced” einstufen.

Viele Grüße,
Andreas

Technorati Tags: ,

Einschränkungen beim Debuggen mit mixed moded Anwendungen im 64-Bit Modus

June 27th, 2010

Hallo,

kürzlich bekam ich vom Visual Studio 2010 Debugger beim Starten einer Anwendung folgende Fehlermeldung:

—————————
Microsoft Visual Studio
—————————
Fehler beim Ausführen des Projekts: Das Programm “…\unittest\bin\Debug\unittest.exe” kann nicht gestartet werden.

Das Debuggen im gemischten Modus für x64-Prozesse wird nur bei Verwendung von Microsoft .NET Framework vor Version 4 unterstützt.
—————————
OK   Hilfe
————————–

Die Konstellation war dabei folgende:

  • Ein reines C#-Programm referenziert eine Assembly, die mit managed C++ erstellt war. Diese Assembly bindet auch native code ein (mixed mode).
  • Als Compiler wurde der vc90 verwendet.
  • Als Targetversion für das .NET-Framework wurde für alle Komponenten 2.0 verwendet.
  • Alle Anwendungen waren als 32-Bit-Anwendungen in Visual Studio 2008 erstellt und wurden von Visual Studio 2010 zur Version 2010 konvertiert.

Für die in C# erstellte (reine .NET) Anwendung war in den Einstellungen als Zielplattform “Any CPU” eingetragen, wie bereits in der Vorgängerversion:

AnyCPU

Nach der Umstellung auf X86 konnte die Anwendung erfolgreich im Debugger gestartet werden.

X86

Die Fehlermeldung ist grundsätzlich ziemlich irreführend. Alle beteiligten Komponenten waren ja explizit für .NET 2.0 konfiguriert.

Oder ist sie gar falsch?

Auf dieser Seite findet man folgendes Zitat:

Debugging im gemischten Modus (Aufrufe von systemeigenem Code bis zu verwalteten Codes, oder umgekehrt) wird für x64-Prozesse unterstützt, wenn der verwaltete Code Microsoft .NET Framework, Version 4 oder höher, verwendet.

Debugging im gemischten Modus wird nicht für IA64-Prozesse oder x64-Prozesse unterstützt, die frühere .NET Framework-Versionen als 4 verwenden.

was ja ein klarer Gegensatz zur oben zitieren Fehlermeldung ist.

Grundsätzlich ist es schon etwas unschön, wenn man für die reine .NET-Komponent nicht mehr “Any CPU” wählen kann, nur weil sie eine mixed mode Assembly nutzt, die im 32-Bit Modus erstellt wurde.

Eine Rolle könnte auch spielen, dass ich inzwischen Windows 7 x64 benutze, während ich zuvor Windows XP X86 verwendet habe.

Viele Grüße,
Andreas

Technorati Tags: , ,


Visual C++ 2010 kann nur für das .NET Framework 4.0 Code erzeugen

June 20th, 2010

Hallo,

vor einiger Zeit bin ich zu dem Schluss gekommen, meine Entwicklungsumgebung auf Basis von Windows 7 und Visual Studio 2010 neu aufzusetzen. Nach der Konvertierung der C++ Projekte wurde in einer Solution mit C# und C++ Projekten folgende Warnung ausgegeben:

Warnung    2    Auf das Projekt “xxx” kann nicht verwiesen werden.  Das Projekt, auf das verwiesen wird, hat eine höhere Frameworkversion (”4.0″) als Ziel.

In der ursprünglichen Solution war für alle Projekt das .NET Framework 2.0 als Targetversion eingetragen. Das war aus gutem Grund so, da die erstellte Anwendung für den Download über das Internet bereit gestellt wird und auf möglichst vielen Computern ohne weitere Vorbereitungen eingesetzt werden soll.

Eine Erklärung für die implizite Erhöhung der Targetversion für Managed C++ Projekte finden sich in diesem Blog-Eintrag mit einem “Visual Studio 2010 C++ Project Upgrade Guide”:

After conversion, managed C++ projects will target the 4.0 Framework by default.  The reason behind this design is that the VS2010 compiler cannot target Framework 2.0, 3.0 or 3.5. The VS2008 compiler must be used to target 2.0, 3.0 or 3.5. To make the converted C++ application build out of box, we decided to move the TargetFrameWorkVersion to 4.0 by default for C++ applications.

Oops! Mit Visual Studio 2010 können keine Managed C++ Anwendungen für .NET Framework Versionen < 4.0 erstellt werden!

Dagegen hilft nur eines:

The VS2008 compiler must be used to target 2.0, 3.0 or 3.5.

D.h. man ist gezwungen, Visual C++ 2008 zusätzlich zu installieren, wenn man Managed C++ Komponenten erstellen will, die .NET Frameworks < 4.0 als Target haben. Die Änderung der Zielversion geht noch nicht mal in der IDE sondern nur durch Änderung der Projektdateien in einem Editor.

Ich betrachte das als erhebliche Einschränkung, da man in diesem Fall Visual Studio 2008 zusätzlich installieren (und ggf. kaufen) muss, sondern dann auch die schönen neuen C++ Features des Compilers nicht mehr nutzen kann.

Generell habe ich den Eindruck, dass Microsoft sich mit Visual Studio 2010 etwas übernommen hat, und irgendwann einfach die Produktfreigabe beschlossen hat, obwohl es noch viele Probleme und Einschränkungen gab (z.B. wie im obigen Blog-Eintrag beschrieben, oder das Fehlen von Intellisense für Managed C++ oder die unscharfe Erscheinung der Default-Fonts auf manchen Betriebsystemen oder der erhöhte Speicherbedarf  oder das aus nicht nachvollziehbaren Gründen umgestellte Hilfesystem, das jetzt eigentlich unbrauchbar ist.).

Auf der Haben-Seite steht für mich ganz klar der neu implementierte Support für Intellisense (bei native C++ Projekten). Das funktioniert jetzt viel besser als mit Visual C++ und verbessert die Produktivität spürbar.

Viele Grüße,
Andreas

Technorati Tags:

Google vs. Bing

May 8th, 2010

Hallo zusammen,

ich benutzt ja wie die meisten Deutschen in der Regel Google als Suchmaschine. Nun hat ja Microsofts Suchmaschine bing inzwischen einen recht guten Ruf.

Eine kleine Erfahrung hierzu:
Ich arbeite zur Zeit in einem XBRL-Projekt und wollte mir in diesem Zusammenhang einen Eindruck über die XBRL Dimensions Conformance Suite machen. Da die Suche bei Google nicht unmittelbar erfolgreich war, habe ich bing probiert. Hier zum Vergleich die Trefferlisten (die bei Ihnen möglicherweise anders aussehen könnten, falls Google sich Ihre Interessen aufgrund der früher angeklickten Ergebnisse gemerkt hat):

Google:
http://www.xbrl-ru.ru/docs/normative/XDT-CONF-CR4-2009-10-06.rtf
http://www.xbrl.org/2005/XBRL-CONF-CR1-2005-04-25.htm
http://www.xbrl.org/Specification/XDT-REC-2006-09-18.htm

Der erste Link verweist auf ein RTF-Dokument auf einem Server der russischen XBRL-Vereinigung.
Der zweite Link verweist auf die XBRL (Standard, nicht Dimensions) Conformance Suite, zudem noch auf eine ältere, obsolete Version.
Der dritte Link verweist auf die Spezifikation von XBRL Dimensions, in der man dann aber auch keinen weiteren, konkreten Hinweis auf die Conformance Suite für XBRL Dimensions findet.
Auch die weiteren Treffer auf der ersten Seite führen einen nicht zum Ziel.

Bing:
http://www.xbrl.org/2006/XDT-CONF-CR3-2006-06-06.htm

Und dieser Link ist gleich ein Volltreffer, es ist genau die Übersichtsseite zur XBRL Dimensions Conformance Suite, die gleich am Anfang auch den gesuchten Download-Link zum zip-Archiv mit den Dateien enthält.

Also bezogen auf diese Anfrage klarer Vorteil für bing!

Viele Grüße,
Andreas

Technorati Tags: , ,

DoDragDrop und SelectedNode in WinForms TreeViews

November 30th, 2009

Hallo,

kürzlich fiel mir ein überraschender Effekt im Zusammenhang mit WinForms TreeViews und drag and drop auf. Fall man im MouseDown-Event eine DragDrop-Operation mit der Methode DoDragDrop() startet, wird der selektierte Knoten nicht auf den angeklickten Knoten gesetzt.

In folgendem Beispiel wurde der Knoten “BasicActivities” angeklickt und damit zum selected node. Anschließend wurde der Knoten ActivityFinalNode angeklickt. Der Focus-ähnliche Rahmen um den Knoten “BasicActivities” blieb aber erhalten:

SelektierterKnotenFalsch

Das hat zur Konsequenz, dass der zuvor selektierte Knoten “BasicActivities” nach einer anschließenden Mousebewegung ohne click wieder selektiert wird.

Dieses Verhalten tritt nicht auf, wenn der Aufruf der Methode DoDragDrop() unterbleibt.

Wenn man den Knoten im MouseDown-Event explizit selektiert (wie hier beschrieben), tritt dieser Effekt nicht auf und das TreeView verhält sich wie gewohnt.

theTreeView.SelectedNode = nodeAt;
DoDragDrop(nodeAt.TheClass, DragDropEffects.Copy);

Viele Grüße,
Andreas

Technorati Tags: ,

Wie kann man native Methoden in managed C++ Klassen nutzen?

October 4th, 2009

Hallo,

Microsoft hat mit der Einführung des .NET-Frameworks auch C++-Erweiterungen (C++/CLI) definiert, mit denen vorhandener C++ source code für .NET-Anwendungen verfügbar gemacht werden kann.

Die Intention dabei war die Steigerung der Akzeptanz des .NET-Frameworks, da es relativ einfach gemacht wird, bereits vorhandenen C++ code in .NET-Anwendungen zu integrieren. Meiner persönlichen Erfahrung nach geht das sehr gut, d.h. es ist ziemlich einfach vorhanden C++ code mit C++/CLI .NET-tauglich zu machen und die entstandenen Assemblys haben keine nennenswerten Einschränkungen (abgesehen davon, dass sie nur für die Plattform geeignet sind, für die der native code kompiliert wurde).

Der übliche Weg besteht darin eine neue Assembly zu erstellen, die C++/CLI Klassen (und ggf. native Klassen) enthält. Diese Klassen rufen dann den eigentlichen legacy code, typischerweise in bereits vorhandenen Libraries/DLLs.

Folgende Frage stellt sich bei der Erstellung eines Managed C++ Wrappers um vorhanden C++ code schnell:

Wie kann ich innerhalb des .NET-Wrappers native Datenstrukturen zwischen managed Klassen austauschen?

Dies ist grundsätzlich nicht ohne weiteres möglich, da in der öffentlichen Schnittstelle nur CLR-kompatible Datentypen verwendet werden dürfen (ansonsten könnten nicht alle Elemente der Schnittstelle von anderen .NET kompatiblen Komponenten konsumiert werden).

Es ist allerdings möglich, private Methoden zu definieren, die nicht CLR-konforme Datentypen konsumieren oder zurückgeben dürfen. Damit solche Methoden von anderen Klassen in der C++/CLI Wrapper-Assembly gerufen werden dürfen, müsste man alle diese Klassen als friend definieren, was eine etwas unbefriedigende Lösung ist.

Diese Überlegung führt aber zur optimalen Lösung: die Deklaration der entsprechenden Methoden als public private. public private ist in C++/CLI die Entsprechung zu internal in C# und bedeutet “sichtbar innerhalb der Assembly”.
Da die entsprechenden Methoden nur von den C++-Klassen innerhalb der Wrapper-Assembly gerufen werden, gibt es keinen Grund sie zu verbieten (was der Compiler dann auch nicht macht).

Viele Grüße,
Andreas

Technorati Tags: ,

Diplom-Informatiker(FH) verdienen mehr als Informatiker von der Universität?

August 3rd, 2009

Hallo,

die  “Beruf und Karriere”-Beilage der Süddeutschen Zeitung vom 1./2.08.09 enthielt einen interssanten Artikel mit dem Titel “Uni-Abgänger verdienen mehr als FH-Absolventen”.

Darin wurden die Ergebnisse einer Befragung von mehr 5000 Absolventen des Jahrgangs 1997 veröffentlicht. Im Durchschnitt verdienten Uni-Abgänger 10 Jahre nach Ende ihres Studiums 64.300,00 EUR während FH-Absolventen 59.400,00 EUR verdienten.

Soweit entspricht das etwa dem was man erwarten würde.

Überraschenderweise scheint das für die Informatik nicht zu gelten, hier verdienten Uni-Abgänger im Schnitt 70.800,00 EUR und FH-Abgänger 77.300,00 EUR. Das sind rund 10% mehr!

Ich selbst habe ebenfalls trotz allgemeiner Hochschulreife an der FH studiert und war mit dieser Entscheidung sehr zufrieden. Ich habe in den beiden Praktikumsemestern in zwei verschiedenen Unternehmen gearbeitet und auch die Diplomarbeit in einem (dritten) Unternehmen geschrieben. Dabei habe ich sehr viel gelernt, wertvolle Kontakte geknüpft und auch meine erste Stelle nach dem Studium gefunden.

Interessehalber noch die Ergebnisse für die anderen Fächer (erstgenannt die Gehälter der Uni-Absolventen):

Bauingenieur: 56.100,00 gegenüber 49.700,00
Elektrotechnik: 70.900,00 gegenüber 64.200,00
Maschinenbau: 76.200,00 gegenüber 62.900,00

Auffällig ist auch der große Abstand bei den Maschinenbauern.

Viele Grüße,
Andreas

Technorati Tags: , , , , ,

Entwicklung von C++ COM-Komponenten mit Visual Studio als eingeschränkter Benutzer

July 20th, 2009

Hallo,

es gibt eine klare Empfehlung für die tägliche Arbeit auf einem Computer mit Windows XP ein Konto mit eingeschränkten Rechten zu verwenden. Der Hauptgrund ist die damit stark reduzierte Wahrscheinlichkeit einem Virus oder anderer Malware zum Opfer zu fallen.

Für Entwickler gibt es noch einen weiteren, wesentlichen Grund für die Verwendung eines Kontos mit eingeschränkten Rechten: sie testen damit automatisch, ob die entwickelte Software auch mit eingeschränkten Rechten funktioniert – was gut geschriebene Software machen sollte.

Dummerweise bekommt man bei diesem vorbildlichen Vorgehen ein Problem, wenn man eine ATL COM Komponente erzeugt. Für diesen Projekttyp aktiviert Visual Studio die Linker Option “Ausgabe registrieren”.
Damit wird nach erfolgreichem Linken der Komponente regsvr32 /s aufgerufen, um die frisch erstellte Library zu registrieren. Dieser Aufruf scheitert bei Verwendung eines Kontos mit eingeschränkten Rechten da die Registrierung von COM-Komponenten Administrator-Rechte erfordert:


Project : error PRJ0050: Fehler beim Registrieren der Ausgabe. Vergewissern Sie sich, dass Sie über die entsprechenden Berechtigungen zum Ändern der Registrierung verfügen.

Für solche Fälle ist die Verwendung des Kommandos runas eine naheliegende Option aber leider hat man auf die von Visual Studio erzeugte Programmzeile für den Aufruf von regsvr32 keinen Einfluss, diese ist nämlich Teil der Visual Studio Programmierschnittstelle und damit nicht direkt zugänglich.

Eine einfache Lösung besteht darin, die oben genannte Linker-Option “Ausgabe registrieren” zu deaktivieren und ein eigenes “Postbuildereigenis” für das Projekt zu definieren. Dieses könnte z.B. so aussehen:


runas /user:administrator /savecred "regsvr32 /s $(TargetPath)"

Damit das funktioniert muss man einmal den Befehl in einem Kommandofenster eingeben und dann nach der Aufforderung das Administrator-Password eingeben. Bei jedem weiteren Aufruf mit /savecred wird dann das zuletzt verwendete Passwort automatisch verwendet. Damit ist vermieden, dass das Administrator-Password im Klartext in einer Visual Studio Projektdatei steht, was eine erhebliche Sicherheitslücke darstellen würde.

Falls man das gemerkte Passwort später wieder löschen möchte: Systemsteuerung/Benutzerkonten/Eigene Netzwerkkennwörter verwalten.

Viele Grüße,
Andreas

Technorati Tags: , , , ,

Bitte aktivieren Sie JavaScript…wofür eigentlich?

June 23rd, 2009

Hallo,

nachdem mich das Finanzamt an die Abgabe der Steuererklärung erinnert hat, habe ich mein Wiso Sparbuch 2009 gestartet und natürlich die schöne Suche nach Aktualisierungen gestartet.
Nach kurzer Zeit erscheint die Meldung:

Sie haben JavaScript deaktiviert. Damit sind wichtige Funktionen dieses Programms nicht verfügbar.
Weitere Informationen zu JavaScript und wie Sie JavaScript aktivieren finden Sie hier.

Bitte aktivieren Sie JavaScript und starten das Programm dann erneut.

Was soll denn bitte diese Meldung? Ich habe eine FAT Client Anwendung zur Abgabe meiner Steuererklärung gestartet. Wo und wie soll ich denn nun JavaScript aktivieren?
(Wer nun denkt, in obiger Meldung wäre “hier” ein Link, den muss ich enttäuschen)

Hallo Ihr Buhl-Programmierer! Schon mal daran gedacht, dass Ihre Software vielleicht von Personen eingesetzt wird, die mit einer solchen Meldung nicht zurechtkommen? Oder von Personen, die keine Lust haben ihren PC in einen Bot voller Malware zu transformieren?

Um dem Ganzen noch die Krone aufzusetzen, startet beim Klick auf den Link “Support” in obigem Dialog der Internet Explorer, obwohl ich den Firefox als Standardbrowser konfiguriert habe. Und die Suche in der Hilfe geht nicht ohne…JavaScript.

Aber als Entwickler einer Software zur Abgabe von optional verschlüsselten Steuererklärungen hat man mit Themen wie Vertraulichkeit und Sicherheit natürlich überhaupt nichts zu tun.

Unnötig zu erwähnen, dass bis zur letztjährigen Ausgabe der Update-Mechanismus von Wiso-Sparbuch auch ohne JavaScript funktioniert hat.

Ach und noch etwas, Windows 7 kommt in Europa ohne Browser auf den Markt…

Viele Grüße,
Andreas

Technorati Tags: ,

Prüfen auf Schreibrechte für eine Datei in C#

February 28th, 2009

Hallo,

manchmal möchte man wissen, ob ein bestimmter Benutzer bestimmte Rechte (z.B. Schreibrechte) für eine bestimmte Datei besitzt. Wie sich herausstellt, ist diese Anforderung alles andere als leicht umzusetzen, weil dabei viele verschiedene Aspekte eine Rolle spielen. Die Vorgehensweise sieht prinzipiell so aus:

  • Abfragen der Access Control Listen für die Datei
  • Itererieren über alle Einträge und prüfen ob man für die Kennung oder die Gruppe des gewünschten Benutzers Einträge findet
  • Dabei die Präzedenz der Einträge beachten (explizite kommen vor vererbten Regeln, “Deny”-Regeln kommen for “Allow”-Regeln)

Den nicht unerheblichen Code hat dankenswerterweise Bruce Hatt in einem Artikel auf CodeProject.com veröffentlicht.

Man sollte bedenken, dass die Möglichkeit in eine Datei zu schreiben zusätzlich durch das “ReadOnly-flag” und die .NET Code Access Security eingeschränkt sein könnte. Beides wird in dieser Klasse nicht berücksichtigt.

Die Prüfung auf das ReadOnly-flag könnte man so schreiben:

FileAttributes attrs = File.GetAttributes(fileName);
 
if ((attrs &amp; FileAttributes.ReadOnly) != 0)
{
    readOnly = true;
}

Und für die Prüfung im Rahmen der CAS könnte man folgenden Code verwenden:

FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.Write, fileName);
try
{
    fp.Demand();
}
 
catch (SecurityException)
{
    readOnly = true;
}

Wenn es nur um die Prüfung auf Schreibrechte geht, hört man oft den Vorschlag, einfach den Schreibvorgang auszuführen und ggf. die geworfene Exception zu fangen. Dieser Vorschlag ist aber nicht immer geeignet. In meinem Fall war es so, dass ich an einer Anwendung arbeite, in der Dateien editiert werden können. Falls Dateien nicht geschrieben werden können, soll dies visualisiert werden. Man möchte aber vermeiden, dazu bei jedem Start der Anwendung die zu editierenden Texte zu speichern, da damit der Timestamp verändert wäre, obwohl der Benutzer die Datei gar nicht geändert hat und auch nicht speichern wollte.

Viele Grüße,
Andreas

Technorati Tags: ,