C/C++ programming

From KolibriOS wiki
Revision as of 14:09, 21 March 2013 by Asiekierka (talk | contribs) (Asiekierka moved page High level programming to C/C++ programming: Modularity - Diamond's pages are large)
Jump to navigation Jump to search

Visual C++ 6/.NET/2005

  • License: command-line version (Visual C++ Toolkit, compiler/linker, standard include files and RTL libraries) is free (http://microsoft.com, search on site), full version (IDE, RTL sources) is commercial,
  • Available Kolibri libraries: LZMA compression library lzmapack.lib; any code, which does not use OS calls and is compiled to object files understandable by the Microsoft linker, can be used (in particular, the many C libraries). Unfortunately, this does not apply to standard RTL (Run-Time Library), so all missing functions must be implemented by hand. However, some of them are already written.
  • Examples: ac97snd, fara, xonix (the sources are included in the sources of the distributive in folders programs\Serge\ac97snd, programs\Diamond\fara, programs\Diamond\xonix correspondingly)
  • Generated code format: 32-bit PE and (for later versions) 64-bit PE64 code depending on used format
  • Environment/platform: Windows, command line or IDE

Visual C++ is one from the best optimizing C++ compilers. Command-line compiler is distributed by Microsoft for free, for IDE one must pay (at least for licensed version :-) ), so both variants are examined here. The version VC6, though written enough time ago, is still popular, the versions VS.NET and VS2005 like to brake.

VC package (more strictly, the linker link.exe) generates only PE-files, so 32-bitness is not a problem, but creation of binary files is tricky.

Under work in IDE let us at first create project: (for VC6) File->New->Projects->Win32 Application, Project name: hello, (for VS) File->New->Project->Visual C++,General->Empty Project, Name: hello, for VC6 the wizard will appear, say to it "An empty project", accept seriousness of our intensions by pressing OK in the last dialog window and we will get fully according to our wishes the empty project with two configurations. It is recommended to delete the configuration Debug right away (for VC6 Build->Configurations->button Remove, for VS Build->Configuration Manager->(in listbox)Edit->button Remove), as the VC debugger is certainly useless in this context. Now let us add to the project (for VC6 Project->Add to Project->Files, for VS Project->Add Existing Item) include files kosSyst.h, KosFile.h, mcsmemm.h and source files kosSyst.cpp, KosFile.cpp, mcsmemm.cpp (are included to examples attached to the article - slightly modified variant from distributive sources to allow compilation in VC6). Apropos, the appearing dialog supports multiple choice (with holded Ctrl). Next, create main file hello.cpp (or main.cpp, or any other name) (for VC6 File->New->Files->C++ Source File, File name: hello, for VS File->New->File->Visual C++,C++ File, then File->Save source1.cpp As, then File->Move hello.cpp into->hello) and next write the code. It is recommended to learn kosSyst.h, this file contains prototypes of system calls wrappers.

#include "kosSyst.h"
#include "kosFile.h"

const char header[] = "HelloWorld test";
const char string[] = "Hello, World!";

void draw_window(void)
{
	// start redraw
	kos_WindowRedrawStatus(1);
	// define&draw window
	kos_DefineAndDrawWindow(10,40,150,50,
		0x33,0xFFFFFF,0,0,(Dword)header);
	// display string
	kos_WriteTextToWindow(30,10,8,0,(char*)string,0);
	// end redraw
	kos_WindowRedrawStatus(2);
}

void kos_Main()
{
	draw_window();
	for (;;)
	{
		switch (kos_WaitForEvent())
		{
		case 1:
			draw_window();
			break;
		case 2:
			// key pressed, read it and ignore
			Byte keyCode;
			kos_GetKey(keyCode);
			break;
		case 3:
			// button pressed; we have only one button, close
			kos_ExitApp();
		}
	}
}

Now let us tune compilation. We can not use RTL-library, because it will force link to Windows-libraries, so for VC6 on the tab "Project->Settings->Link" in "Category: Input" clear editbox "Object/library modules" and set checkbox "Ignore all default libraries". Entry point is the function crtStartUp, so in "Category: Output" set "Entry-point symbol:" in "crtStartUp". Moreover, in "Project Options" it is recommended to add option "/align:16" (this is not necessary, but greatly decreases binary size). For VS the corresponding dialog is called by "Project->hello Properties" and has treeview instead of tabs, similar actions are executed as follows: Configuration Properties->Linker->Input-> Ignore All Default Libraries: Yes, Linker->Advanced->Entry Point: crtStartUp, Linker->Command Line->Additional options: /align:16. Moreover, VS requires obvious subsystem guideline: Linker->System->SubSystem (select any, it has no influence) and disable at compilation buffer overflow checks and RTTI (they use RTL): C/C++ ->Code Generation->Buffer Security Check: No, C/C++ ->Language->Enable Run-Time Type Info: No. Also manifest inserted by VS has no value for us, so Linker->Manifest File->Generate Manifest: No. Now the compiler can already generate code, but it will be created in PE format. The main idea is to pass generated PE-file through the program pe2kos.exe, which will change its format to used in Kolibri. pe2kos.exe is included with the sources to the distributive sources (the folder "develop\pe2kos"), and also without the sources to examples attached to the article. (There exists also another way, it is shown in MASM chapter, description of linking.) Kolibri-binaries are loaded at zero address, Kolibri-header will be created in the file beginning instead of PE-header, so base address must be set (at the same tab - "Output" for VC6, "Linker->Advanced" for VS - field "Base address") to 0, VS also requires "Fixed Base Address" set to "Image must be loaded at a fixed address (/FIXED)" (VC6 by default does not generate fixups itself).

Hll vc1.gif

Hll vc2.gif

The remaining part is to setup call to pe2kos. For VC6: Project->Settings->Custom Build, for VS: Project->hello Properties->Custom Build Step. In the editbox Commands/Command Line write

pe2kos Release\hello.exe hello

(pe2kos is assumed to be placed either in one from PATH-folders or in project folder), in the editbox Outputs write binary name - hello, it will be generated in the project folder. The build process is now as usually - either F7, or Build->Build hello.exe(VC)/Build->Build Solution(VS), or corresponding button on toolbar.

Now, let us work with the command line. At first, set required environment variables. When VC Toolkit, VC6 or VS are installing, they create in the corresponding partition of main menu the item "... Command Prompt", which calls console, sets up used environment and waits for user actions. One can also independently run console and execute the file vcvars32.bat. Next, go to work folder (drive is changed by the command "X:", folder on drive - by the command "cd \folder1\folder2"). Following assumes that the folder already contains kosFile.cpp,kosSyst.cpp,mcsmemm.cpp,kosFile.h,kosSyst.h,mcsmemm.h and created hello.cpp. Required compilation options are the same as in IDE, but now they are selected not through GUI, but in command line.

Compilation before VS2005:

cl /c /O2 /nologo hello.cpp kosFile.cpp kosSyst.cpp mcsmemm.cpp
link /nologo /entry:crtStartUp /subsystem:native /base:0 /fixed
	/align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
pe2kos hello.exe hello

Hll vc3.gif

VS2005 adds new options:

cl /c /O2 /nologo /GS- /GR- hello.cpp kosFile.cpp kosSyst.cpp mcsmemm.cpp
link /nologo /manifest:no /entry:crtStartUp /subsystem:native /base:0 /fixed
	/align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
pe2kos hello.exe hello

Hll vc4.gif