Daten|teiler
Kopieren als Kulturtechnik

Ein C-Programm unter Windows kompilieren

4. Dezember 2013 von Christian Imhorst

Ein C-Programm unter Windows zu kompilieren ist leider nicht ganz so einfach, wie einen C-Compiler unter Gnu/Linux anzuwerfen. Das Ganze soll natürlich auf der Konsole stattfinden. Mit dem kostenlosen Visual Studio C++ 2010 Express geht das aber recht fix, solange es sich zumindest um kleine Projekte in C handelt.

Nach der Installation von Visual C++ 2010 Express muss noch die Umgebung zum Kompilieren vorbereitet werden. In der Microsoft Shell cmd.exe führt man dazu folgende Batch-Datei mit Administrationsrechten aus, sofern man ein Windows mit 64bit hat. In der 32bit-Ausgabe kann man das „(x86)“ im Programm-Pfad weglassen.

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86

Wenn man den Batch nicht ausführt, bekommt man übrigens folgende Fehlermeldung:

Das Programm kann nicht gestartet werden, da mspdb100.dll auf dem Computer fehlt. Installieren Sie das Programm erneut, um das Problem zu beheben.

Zum Testen kann man ein kleines Hallo Welt-Programm schnell im Notepad schreiben:

//HalloWelt.c
 
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    if (puts("Hallo Welt!") == EOF)
        return EXIT_FAILURE;
    else
        return EXIT_SUCCESS;
}

Das Kompilieren erfolgt dann wieder in der Microsoft Shell, in der man vorher noch in den Ordner mit dem Quellcode gesprungen ist:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe" HalloWelt.c

Das Ergebnis ist dann das Konsolen-Programm HalloWelt.exe. Neben ausführbaren Dateien kann man auch Bibliotheken erstellen, unter Windows zum Beispiel eine dynamische Bibliothek mit „.DLL“ als Endung. Dazu bauen wir das Hallo Welt-Programm allerdings etwas um. Einige Programm-Teile wandern zusammen mit neuen in eine Header-Datei:

//HalloWelt.h
 
#include <stdio.h>
#include <stdlib.h>
 
__declspec(dllexport) void HalloWelt();

In den Quellcode der C-Datei muss dann noch die neue Header-Datei eingefügt werden:

//HalloWelt.c
 
#include "HalloWelt.h"
 
void HalloWelt()
{
    if (puts("Hallo Welt!") == EOF)
        return EXIT_FAILURE;
    else
        return EXIT_SUCCESS;
}

Die Main-Funktion habe ich noch durch ein „HalloWelt()“ ersetzt. Die Bibliothek wird dann in zwei Schritten kompiliert. Im ersten Schritt wird die Objekt-Datei ohne die ausführbare Datei erstellt, indem dem Compiler die Option „/c“ mitgegeben wird:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe" /c HalloWelt.c

Anschließend wird die Objekt-Datei zur Bibliothek „gelinkt“:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe" /DLL /out:HalloWelt.dll HalloWelt.obj

Mit dem Programm link.exe kann man auch gucken, wie es in unserer DLL aussieht:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe" /dump /exports HalloWelt.dll
 
[...]
 
File Type: DLL
 
  Section contains the following exports for HalloWelt.dll
 
    00000000 characteristics
    529DFB7D time date stamp Tue Dec 03 16:40:45 2013
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names
 
    ordinal hint RVA      name
 
          1    0 00001000 HalloWelt
 
  Summary
[...]

Unter „name“ sieht man den Namen unserer Funktion „HalloWelt()“, auf die wir dann zum Beispiel in Python über CTypes zugreifen können.

from ctypes import CDLL
hw = CDLL("HalloWelt.dll")
print hw.HalloWelt()
 
Hallo Welt!

Geschrieben in Programmieren, Windows