Mein Senf zu einer „Controversial Programming Opinion“

Vor kurzem stieß ich auf einen(bzw. mehrere) interessante Blogartikel über sogenannte kontroverse Programmieransichten(Controversial Programming Opinions) und zwar hier, hier und hier.
Wie das so ist, stimmt man mit manchen überein, mit anderen weniger. Es gibt jedoch eine Meinung, zu der ich mich etwas ausführlicher äußern möchte, auch, weil ich selbst damit Erfahrungen machen durfte:

9. C (or C++) should be the first programming language (+24/-5) by hansen j

The first language should NOT be the easy one, it should be one that sets up the student’s mind and prepare it for serious computer science.
C is perfect for that, it forces students to think about memory and all the low level stuff, and at the same time they can learn how to structure their code (it has functions!)

C++ has the added advantage that it really sucks 🙂 thus the students will understand why people had to come up with Java and C#.

Was ist also die Grundempfehlung für Programmierneulinge? Die erste Programmiersprache soll schwer sein und einen auf ernsthafte Computerwissenschaften vorbereiten. Man soll an Speichermanagement usw. denken.
Puh…ich glaube eher nicht, schon allein deshalb, weil nicht jeder, der mit dem Programmieren beginnt, ernsthafte Computerwissenschaften im Sinn hat.

Weiterlesen

C++ Unit-Tests mit googletest(Google C++ Testing Framework)

Ich war gestern und heute auf der Suche nach einem gescheiten Unit-Test-Framework für C++, nachdem ich für .Net und Java bereits NUnit und JUnit ausprobiert hatte. Zusätzlicher Anspruch war, dass das ganze im Visual Studio 2010 funktioniert. Beim Versuch das Boost Unit Test Framework im VS zum Laufen zu bringen, bin ich grandios gescheitert. Daher habe ich mich nach etwas anderem umgesehen und siehe da: Google bietet auch ein Unit Test Framework für C++ an. Da es allerdings auch ein bisschen gedauert hat, bis es endlich funktionierte, möchte ich es hier noch einmal beschreiben.

Hat man also das Framework runtergeladen und an einen Ort seiner Wahl entpackt, muss man den Ordner msvc aufsuchen(in meinem Fall ist der Pfad: C:\GoogleTest\gtest-1.6.0\msvc). Hier gibt es zwei Visual Studio Solution FIles:

  • gtest.sln(nutzt statische Versionen MS Runtime Libraries
  • gtest-md.sln(nutzt DLL Versionen von MS Runtime Libraries)

Ich habe die erste Variante geöffnet und per Wizard in eine VS2010 Solution konvertiert. Nun muss man normalerweise nichts weiter mehr einstellen und nur den Build-Button betätigen. Dies kann man einmal im Debug – und einmal im Release Modus machen. Anschließend sollten für beide Möglichkeiten die notwendigen *.lib-Dateien(unter C:\GoogleTest\gtest-1.6.0\msvc\gtest\Debug bzw. C:\GoogleTest\gtest-1.6.0\msvc\gtest\Release) erstellt worden sein.

Nun kann man sich im Visual Studio ein leeres C++ Projekt anlegen.

Folgende Projekteigenschaften müssen zwingend festgelegt werden:

1. C/C++ –> Zusätzliche Includeverzeichnisse –> C:\GoogleTest\gtest-1.6.0\include;

01

2. C/C++ –> Codegenerierung

  • Multithreaded (/MT) falls googletest im Releasemodus erstellt wurde
  • Multithreaded-Debug (/MTd) falls googletest im Debugmodus erstellt wurde

02

3. Linker –> Allgemein –> Zusätzliche Bibliotheksverweise

  • C:\GoogleTest\gtest-1.6.0\msvc\gtest\Release falls googletest im Releasemodus erstellt wurde
  • C:\GoogleTest\gtest-1.6.0\msvc\gtest\Debug falls googletest im Debugmodus erstellt wurde

03

4. Linker –> Eingabe –> Zusätzliche Abhängigkeiten

  • gtest.lib; gtest_main.lib; falls googletest Bibliotheken verwendet werden, die im Releasemodus erstellt wurden
  • gtestd.lib; gtest_maind.lib falls googletest Bibliotheken verwendet werden, die im Debugmodus erstellt wurden

04

Sind diese Einstellungen vollständig, kann man einen ersten Test mit googletest schreiben. Das Framework unterscheidet sich rein von der Logik her nicht groß von anderen Unit-Test-Frameworks. Man arbeitet mit verschiedenen Assertions und Testmethoden.

Folgender Code zeigt ein einfaches Beispiel:

#include

#include "gtest/gtest.h"

TEST(stringTest, checksIfTextIsCorrect)
{
	std::string s("xyz");
    EXPECT_EQ(s, "xyz");
}

TEST(stringLengthTest, checksIfLengthIsCorrect)
{
	std::string s("xyz");
	EXPECT_EQ(s.length(), 3);
}

int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    RUN_ALL_TESTS();
	std::cin.get();
}

Das Test() Makro legt die Testmethode an. Der erste Parameter ist der Name des Testfalls, der zweite beschreibt, was getestet wird.

In den Methoden teste ich die String-Klasse aus Der C++ Standardbibliothek, einmal die Gleichheit des Strings und einmal die Länge.

In der main()-Methode werden nun alle Tests ausgeführt. Meine Konsolenausgabe sieht folgendermaßen aus:

05

Hier kann man nun begutachten, ob die Tests fehlschlagen oder nicht. Der Screenshot zeigt, dass die String-Klasse für diese Tests zumindest zuverlässig arbeitet.

Wer die Konsole nicht so gern hat, dem steht außerdem noch eine kleine GUI Anwendung zur Verfügung.

Diese ist denkbar einfach zu bedienen. Nach dem Entpacken startet man einfach Guitar.exe. Per Select-Button wählt man die zu testende .exe Datei aus(das Projekt, in dem die Tests liegen). Je nach Modus befindet sich diese .exe Datei im Debug oder Release Ordner des Test-Projektes. Dann reicht ein Klick auf den Go-Button.

In meinem Fall sieht die Ausgabe so aus:

06

Das sieht doch alles schon ganz gut aus. Und vielleicht hilft die Anleitung ja auch dem einen oder anderen :).

OpenSSL Verschlüsselung in C/C++

OpenSSL ist eine relativ bekannte Kryptografie-Bibliothek. Allerdings lässt die Dokumentation an manchen Stellen zu wünschen übrig. Daher hier ein kleines Beispiel, wie man mit OpenSSL und C++ verschlüsseln kann. Gewählt habe ich den Algorithmus Blowfish im Betriebsmodus OFB.

Vorweg der Source Code:

#include <openssl/evp.h>
#include <iostream> 

using namespace std;

int main(){
	char plainText[64];
	const unsigned char initializationVector[8]={2,4,6,8,7,9,11,12};
	const unsigned char key[16]={'*','a','h','w','+','y','q','t',12,2,4,6,8,7,9,'u'};
	unsigned char encryptedBuffer[1024];
	unsigned char decryptedBuffer[1024];
	int bufLength, tmpLength, encryptedTextLength;
	EVP_CIPHER_CTX ctx;

	memset(encryptedBuffer, 0, sizeof(encryptedBuffer));
	memset(decryptedBuffer, 0, sizeof(decryptedBuffer));

	cout <<"String eingeben: ";
	cin.getline(plainText, 64);

	EVP_CIPHER_CTX_init(&ctx);
	EVP_EncryptInit(&ctx, EVP_bf_ofb(), key, initializationVector);

	if(!EVP_EncryptUpdate(&ctx, encryptedBuffer, &bufLength, (unsigned char*)plainText, strlen(plainText))){
		cout <<"Fehler in EncryptUpdate!" << endl;
        return 0;
	}

	if(!EVP_EncryptFinal(&ctx, encryptedBuffer + bufLength, &tmpLength)){
		cout <<"Fehler in EncryptFinal!" << endl;
        return 0;
	}
    
	bufLength += tmpLength;
	encryptedTextLength=bufLength;
	encryptedBuffer[bufLength] = '\0';
	EVP_CIPHER_CTX_cleanup(&ctx);

	cout << "Vor Encryption: " << plainText << endl;
	cout << "Nach Encryption: " << encryptedBuffer << endl;

	EVP_DecryptInit(&ctx, EVP_bf_ofb(), key, initializationVector);

	if(!EVP_DecryptUpdate(&ctx, decryptedBuffer, &bufLength, encryptedBuffer, encryptedTextLength)){
		cout <<"Fehler in EncryptUpdate!" << endl;
        return 0;
	}

	if(!EVP_DecryptFinal(&ctx, decryptedBuffer + bufLength, &tmpLength)){
		cout <<"Fehler in EncryptFinal!" << endl;
        return 0;
	}

	EVP_CIPHER_CTX_cleanup(&ctx);

	cout << "Nach Decryption: " << decryptedBuffer << endl;
	
	cin.get();
	return 0;
}

Weiterlesen

Rezension “Der C++ Programmierer” von Ulrich Breymann

Ein Praxisbuch für alle, Einsteiger und auch Profi, soll es sein. Das verspricht das Buch “Der C++ Programmierer” von Ulrich Breymann, erschienen im Hanser Verlag, auf seiner Rückseite. Ist es das wirklich? Diese und ein paar andere Fragen soll die nachfolgende Rezension klären.

Die Themen

Eingeteilt ist der C++ Programmierer in fünf Teile:

  • Einführung in C++
  • Bausteine komplexer Anwendungen
  • Praktische Methoden und Werkzeuge der Softwareentwicklung
  • Das C++ Rezeptbuch: Tipps und Lösungen für typische Aufgaben
  • Die C++ Standardbibliothek

Weiterlesen

Das Observer Pattern in C++

Über Entwurfsmuster stolpert man als Student eines informatiklastigen Studiengangs ja immer mal wieder. Daher habe ich mir heute ein relativ einfaches und dennoch auch bedeutendes Muster rausgesucht, dessen Funktionsweise ich exemplarisch in C++ erklären möchte: Das Observer Pattern.

Was ist das Observer Pattern bzw. welche Aufgabe hat es?

Angenommen man schreibt ein Programm, das auf bestimmte Ereignisse reagieren soll, zum Beispiel eine Änderung von Werten oder eine Aktualisierung im Allgemeinen. Noch dazu bietet dieses Programm verschiedene Anzeigen, die Daten darstellen und bei einem Update selbiger die Veränderung ebenfalls sofort übernehmen. Dann ist das Observer Pattern genau das richtige.

Wie funktioniert das Observer Pattern in der Theorie?

Weiterlesen