NPRG0 4 1 Programování v C++ Programování v C

45
NPRG041 Programování v C++ Programování v C David Bednárek Filip Zavoral

description

NPRG0 4 1 Programování v C++ Programování v C. David Bednárek Filip Zavoral. C vs. C++. V ývoj 1970-3 první verze C , spole č n ý v ý voj s UNIXem , jádro v C 1978 Kerninghan, Ritchie: The C Progr amming Language 1980 AT &T - " C with Classes" - PowerPoint PPT Presentation

Transcript of NPRG0 4 1 Programování v C++ Programování v C

Page 1: NPRG0 4 1 Programování v C++ Programování v C

NPRG041Programování v C++

Programování v C

David BednárekFilip Zavoral

Page 2: NPRG0 4 1 Programování v C++ Programování v C

Vývoj◦ 1970-3 první verze C, společný vývoj s UNIXem, jádro v C◦ 1978 Kerninghan, Ritchie: The C Programming Language◦ 1983 Rick Mascitti: poprvé název C++◦ 1985 Stroustrup: The C++ Programming Language◦ 1998 ISO/ANSI norma C++◦ 1999 ISO/ANSI norma C - 'C99'◦ 2011+ C++11/14/17

zásadní rozšíření jazyka - lambda, r-values, generic prog., ...

Proč C v 21. století◦ jádra OS, drivery, knihovny◦ GPU, many-core◦ embedded devices, 'pračky'◦ údržba sw

C vs. C++

Page 3: NPRG0 4 1 Programování v C++ Programování v C

... neboli co v C není

OOP◦ classes, inheritance, member functions, constructors and

destructors, virtual functions, access control, pointers to members, static members

Syntax◦ templates, smart pointers, exceptions, references, overloading,

default arguments, namespaces, new/delete, casting, friend, inline, RTTI, auto, lambda, rvalues, concepts, ..., ..., ...

Libraries◦ containers, iterators & algorithms◦ strings◦ streams

C++ jako ostrá nadmnožina C

Page 4: NPRG0 4 1 Programování v C++ Programování v C

bool

struct & enum tags

implicitní konverze - enum, void *

main - return 0;

Odlišnosti C a C++

struct S { int x;};

S s;

struct S { int x;};

struct S s;

typedef struct S_ { int x;} S;

S s;

bool b = true; typedef enum bool_ { FALSE, TRUE} bool;bool b = TRUE;int b2 = a > 1;_Bool b = TRUE;

C99

enum E { NULA };enum E e = NULA;int x = e;int* p = malloc(sizeof( int));

enum E { NULA };E e = NULA;int x = (int)e;int* p = (int*)malloc(sizeof(int));

int main(){ ...}

int main(){ ... return 0;}

C ⊈ C++

Page 5: NPRG0 4 1 Programování v C++ Programování v C

Pole a ukazatele, aritmetika ukazatelů

T a[n]; pole prvků typu T T *p = &a[i]; ukazatel p ukazuje na prvek pole p+j; p+=j; ++ppřičtení - posun o j prvků v rámci

pole p-j odečtení - posun zpět p1-p2 odečtení ukazatelů - počet prvků mezi

int a[5]; int *p;

a[2] = 20; p = &a[2];

a[0] = *p - 15; ++p; *p = 30;

0 1 2 3 4

? ? 20 ? ?

5 ? 20 30 ?

p

p

reference na prvek pole

inkrementace ukazatele

posun na další prvek

a

reference na prvek pole

stejně jako iterátory

Page 6: NPRG0 4 1 Programování v C++ Programování v C

p = &a[1]; *(p+3) = 40;

Operátor []

p[i] *(p+i)

&p[i] p+i

a &a[0]

Automatické konverze pole-ukazatel◦ identifikátor pole se chová jako ukazatel na nultý

prvek Pole nelze přiřazovat ani předávat hodnotou

◦ p = a je ekvivalentní p = &a[0]

5 ? 20 30 40

ppřičtení čísla k ukazateli posun o n prvků

identifikátor pole je ukazatelna svůj nultý prvek

indexování pole (ukazatele) je 'jen' jiný zápis přístupu přes ukazatel

Pole a ukazatele, aritmetika ukazatelů

Page 7: NPRG0 4 1 Programování v C++ Programování v C

Řetězec - pole znaků (char) zakončené nulou◦ konvence, knihovny

"Ahoj"

X proměnná 'X' znaková konstanta - celočíselná hodnota "X" řetězec - ukazatel

Řetězce

'A' 'h' 'o' 'j' '\0'

Každý řetězec musí být vždy ukončen nulou

'A' 'h' 'o' 'j' '\0'

vždy myslet na koncovou nulu !

pozor na uvozovky a apostrofy !

char buffer[4];strcpy( buffer, "Ahoj");

'\0' = 0

kód znaku v použitém kódování

(ASCII, CP1250, ISO8859-2, EBCDIC, ...)

Page 8: NPRG0 4 1 Programování v C++ Programování v C

char s1[] = "Uno";

const char *s2 = "Due";

puts( "Uno");

Řetězcové proměnné a konstanty

'U' 'n' 'o' '\0'

'D' 'u' 'e' '\0'

s1:

s2:

Inicializovaná proměnná typu ukazatel++s2 se přesune na další znak

Inicializované pole (konstantní ukazatel)

++s1 nelze! anonymní globální proměnnáconst char[]

ekvivalent globální proměnné typu const char[ ] inicializované obsahem konstanty

... = { 'U', 'n', 'o', 0 };

Page 9: NPRG0 4 1 Programování v C++ Programování v C

Délka řetězce – různé implementace

int i = 0;while ( *s != '\0') { ++i; ++s;}return i;

int strlen ( const char* s){ int i = 0; while ( s[i] != '\0') { ++i; } return i;}

char *p = s;while (*p++) ;return p-s-1;

for( i=0; *s != '\0'; ++i) ++s;

for( i=0; *s != '\0'; ++i, ++s) ;

int i=0;while ( *s++ != '\0') ++i;

int i=0;while ( *s++) ++i;

přístup přes ukazatel

více inkrementací prázdné tělo

nezapomenout na ';' !!

složitější podmínka:test nenulovostiinkrementace

ukazatele

while(a!=0) while(a)podmínka je splněnapokud je nenulová

rozdíl ukazatelů = počet prvků mezi nimi

pozor na ± 1 !

Page 10: NPRG0 4 1 Programování v C++ Programování v C

Řetězce – chyby při kopírování

D o b r y d e n \0pozdrav

buf

char buf[6];char pozdrav[] = "Dobry den";strcpy( buf, pozdrav);

D o b r y d e n \0

vždy pozor na dostatek místafunkce nic nekontroluje !!!váš program provedl...

char *ptr;char pozdrav[] = "Ahoj";strcpy( ptr, pozdrav);

kopírování na neinicializovaný ukazatel !!!váš program provedl...

A h o j \0pozdrav

ptr?

A h o j \0ptr

neinicializovaný !!!

Page 11: NPRG0 4 1 Programování v C++ Programování v C

Naprosto chybné řešení◦ Nekontroluje přetečení pole buf◦ Vrací odkaz na lokální proměnnou, která v okamžiku návratu zaniká

Vracení řetězců - lokální proměnná

char * cele_jmeno( const char * jm, const char * prijm){ char buf[ 100]; strcpy( buf, jm); strcat( buf, " "); strcat( buf, prijm); return buf;}

string cele_jmeno( const string& jm, const string& prijm){ return jm + " " + prijm;}

Page 12: NPRG0 4 1 Programování v C++ Programování v C

Chybné řešení◦ Nekontroluje přetečení pole buf◦ Používá statickou proměnnou

zbytečně zabírá místo i v době, kdy funkce není vyvolána opakovaná volání ji sdílejí:

podmínka nikdy nebude splněna, protože strcmp vždy dostane stejné ukazatele na totéž pole buf

Vracení řetězců - statická proměnná

char * cele_jmeno( const char * jm, const char * prijm){ static char buf[ 100]; strcpy( buf, jm); strcat( buf, " "); strcat( buf, prijm); return buf;}

if ( strcmp( cele_jmeno( j1, p1), cele_jmeno( j2, p2)) )

Page 13: NPRG0 4 1 Programování v C++ Programování v C

Funkční řešení, ale nebezpečné◦ Nekontroluje přetečení pole buf◦ Pokud volající nemá spolehlivý horní odhad velikostí jména a

příjmení, nemůže tuto funkci bezpečně volat

◦ Většina C knihovenale funguje podobně

Vracení řetězců - parametr

void cele_jmeno( char * buf, const char * jm, const char * prijm){ strcpy( buf, jm); strcat( buf, " "); strcat( buf, prijm);}

void tisk( const char * jm, const char * prijm){ char buf[ 100]; cele_jmeno( buf, jm, prijm); puts( buf);}

Page 14: NPRG0 4 1 Programování v C++ Programování v C

Vracení řetězců - bezpečné řešeníint cele_jmeno( char * buf, size_t bufsize,

const char * jm,const char * prijm)

{ size_t lj = strlen( jm); size_t lp = strlen( prijm); if ( lj + lp + 2 > bufsize ) { /* error */ return -1; } memcpy( buf, jm, lj); buf[ lj] = ' '; memcpy( buf + lj + 1, prijm, lp); buf[ lj + lp + 1] = 0; return lj + lp + 1;}

void tisk( const char * jm, const char * prijm){ enum { N = 100 }; char buf[ N]; if( cele_jmeno( buf, N, jm, prijm) > 0) puts( buf);}

max velikost pole

kontrola korektnostivýsledku

kontrola velikosti polepozor na mezeru a konec!

kopírování jednotlivých částí

návrat výsledné délky

Page 15: NPRG0 4 1 Programování v C++ Programování v C

Kombinace typových konstrukcí

A * x[10] pole ukazatelů

A (* x)[10] ukazatel na pole

A * x() funkce vracející ukazatel

A (* x)() ukazatel na funkci

A x[10]() pole funkcí - zakázáno

A (* x[10])() pole ukazatelů na funkci

A x()[10] funkce vracející pole - zakázáno

A (* x())[10] funkce vracející ukazatel na pole

čtení deklarací: od identifikátoru doprava, až to nepůjde, tak doleva

typicky se nepoužívápole = ukazatel na 1. prvek

Page 16: NPRG0 4 1 Programování v C++ Programování v C

int*(*pf[10])(void);

int*(*maso(int*(*p1)(void),int*(*p2)(void)))(void);

Kombinace typových konstrukcí

co to je za maso ???

Page 17: NPRG0 4 1 Programování v C++ Programování v C

int*(*pf[10])(void);int*(*maso(int*(*p1)(void),int*(*p2)(void)))(void);

typedef int* fce( void);fce * pf [10];fce * maso( fce* p1, fce* p2);

Kombinace typových konstrukcí

použitím typedefse výrazně zpřehlední kód

Page 18: NPRG0 4 1 Programování v C++ Programování v C

OOP v Cclass A {public: A() : x_(1) {} int f( int y) { return x_ + y; }private: int x_;};

A* a = new A;a->f(2);

typedef struct A_ { int x_;} A;

int A_init( A* a) { a->x_ = 1; }int A_f( A* a, int y) { return a->x_ + y; }

A* a = malloc( sizeof( A));A_init(a);A_f(a,2);

explicitní this

explicitní prefix nebo možnost kolize

nemožnost přetížení

beztypová alokace

absence ochrany

absencekonstruktorua destruktoru

explicitní inicializace

Page 19: NPRG0 4 1 Programování v C++ Programování v C

Pozdní vazba v Cclass A { virtual int f(void) { return 1; }};

class B : public A { virtual int f(void) { return 2; }}

A* a = new B;a->f();

typedef int fnc(void);typedef struct A_ { fnc* f_;} A;void A_init( A* a, fnc* f) { a->f_ = f; }int A_f( A* a) { return (*a->f_)(); }int A_f_body() { return 1; }int B_f_body() { return 2; }

A* a = malloc( sizeof( A));A_init( a, B_f_body);A_f( a);

VMTkonstruktor inicializace

VMT

virtual method

'odvozená metoda'

zavolá se B_f

ruční inicializace

Page 20: NPRG0 4 1 Programování v C++ Programování v C

Parametry příkazové řádky

C:\> myprog.exe -n -w a.txt b.txt

0

m y p r o g . e x e \0

- n \0

- w \0

a . t x t \0

b . t x t \0

argv

5argc

int main( int argc, char** argv)

pole řetězců(ukazatelů na char)

Počet parametrůvčetně názvu programu != počet ukazatelů v argv

vector<string> arg( argv, argv+argc);

Page 21: NPRG0 4 1 Programování v C++ Programování v C

int main( int argc, char** argv){ int n=0, w=0; while( *++argv && **argv=='-') { switch( argv[0][1]) { case 'n': n = 1; break; case 'w': w = 1; break; default: error(); } } if( !argv[0] || !argv[1]) error(); doit( argv[0], argv[1], n, w); return 0;}

options

usage: myprog [-n] [-w] fileA fileB

nastavení přepínače

zbývající parametry

výkonná funkce

p r g . e x e \0

- n \0

- w \0

a . t x t \0

b . t x t \0

0

argv

Zpracování příkazové řádky

Page 22: NPRG0 4 1 Programování v C++ Programování v C

int main( int argc, char** argv){ int n=0, w=0; int x = 0; char* f = 0; while( *++argv && **argv=='-') { switch( argv[0][1]) { case 'n': n = 1; break; case 'w': w = 1; break; case 'x': x = atoi( *argv+2; break; case 'f': f = *argv+2; break; default: error(); } } if( !argv[0] || !argv[1]) error(); doit( argv[0], argv[1], n, w, x, f); return 0;}

číselný parametr

usage: myprog [-n] [-w] [-x123] [-ffilename] fileA fileB

řetězcový parametr

- x 1 2 3 \0

- f f i l ...

argv

Zpracování příkazové řádky

Page 23: NPRG0 4 1 Programování v C++ Programování v C

int main( int argc, char** argv){ int n=0, w=0; int x = 0; char* f = 0; while( *++argv && **argv=='-') { switch( argv[0][1]) { case 'n': n = 1; break; case 'w': w = 1; break; case 'x': x = atoi( argv[0]+2); break; case 'f': if( argv[0][2]) f = *argv+2;

else f = *++argv; break;

default: error(); } } if( !argv[0] || !argv[1]) error(); doit( argv[0], argv[1], n, w, x, f); return 0;}

-ffile

usage: myprog [-n] [-w] [-x123] [-f filename] fileA fileB

-f file

- f \0

argv- f f i l ...

f i l e n ...

Zpracování příkazové řádky

≡ &(argv[0][2])

Page 24: NPRG0 4 1 Programování v C++ Programování v C

Variabilní argumenty

int sum( int num, ...) { int rv = 0; va_list argptr; va_start( argptr, num); for( ; num > 0; num--) { rv += va_arg( argptr, int); } va_end( argptr); return rv;} int answer = sum( 4, 4, 3, 2, 1);

opravdu '...'

speciální typ

inicializace

přístup

ukončení

#include <stdarg.h>typedef va_list ????va_start( va_list argptr, last_parm);va_arg( va_list argptr, type);va_end( va_list argptr );

korektnost parametrů musí zajistit uživatel

funkce

Náhrada v C++: Variadic Templates

typ !

Page 25: NPRG0 4 1 Programování v C++ Programování v C

int printf( const char * format, ...);◦ % [flags] [width] [.precision] [opt_pref] type ◦ %c - char - znak◦ %d - int - decimálně◦ %x - int - šestnáctkově◦ %ld - long◦ %f - double - s desetinnou tečkou◦ %g - double - s exponentem◦ %s - char * - řetězec

printf

fprintf( FILE*, sprintf( char*,swprintf( wchar_t*,_snprintf( char*, int n,_scprintf(...

místo width a/nebo precision znak *

hodnota následujícího parametru

width: min. počet míst na výstupuprecision: max. počet zpracovávaných

znaků

#include <stdio.h>printf( "Ahoj %s dnes je %d.%d.", "Babi", 8, 1);

shodu formátu a parametrů musí zajistit programátor

neshoda: nedefinované chování

Page 26: NPRG0 4 1 Programování v C++ Programování v C

printf

printf(":%c:%6d:%08X:%7.3f:%7.3f:\n", 'a', 17, 1234, -1234.56, -1234.5678);

printf(":%s:%6s:%6s:%-6s:%-6.3s:%.3s:\n","ahoj", "ahoj", "ahojbabi", "ahoj", "ahoj", "ahoj");

printf(":%*d:%-*.*s:\n", 6, 17, 6, 3, "ahoj");

printf(":%c:%c:%d:%s:\n", 0xffeedd41, "ahoj", "ahoj", 'a');

:a:▫▫▫▫17:000004D2:▫▫-1234.560:▫▫-1234.568:

:ahoj:▫▫ahoj:ahojbabi:ahoj▫▫:aho▫▫▫:aho:

:▫▫▫▫17:aho▫▫▫:

:A::78263451:●

Unhandled exception at 0x0041470c :Access violation reading location

0x00000061

Page 27: NPRG0 4 1 Programování v C++ Programování v C

#include <stdio.h>

FILE* fp;int c;

if( !(fp = fopen("c:\\f.txt", "r")))error();

while( (c = getc( fp)) != EOF)putchar( c);

fclose( fp);

Práce se soubory

typ 'soubor'(ukazatel na strukturu)

otevření souborukonvence dle OS

pozor na '\\' !!!

konstanta v stdio.hrůzná od všech možných dat

mode

soubor ex.

soubor neex.

seek

r R Error 0

w Del, W W 0

a W W End

r+ R/W Error 0

w+ Del, R/W R/W 0

a+ R/W R/W End

+: vždy čtení i zápis

a: otevřít na konci

r: soubor musí existovat

w: soubor se smaže

Page 28: NPRG0 4 1 Programování v C++ Programování v C

Textový soubor◦ konverze konců řádek ('\n') na platformově závislou vnější reprezentaci◦ typicky 0x0D 0x0A (Win) nebo 0x0A (Unix)◦ konverze je automatická, programátor se o to nemusí starat◦ vhodné pro ukládání lidsky čitelných dat◦ getc/putc, fgets/fputs, fprintf, ...◦ chování fseek/ftell na '\n' nedefinován - nepoužívat

Binární soubor◦ žádné konverze se neprovádí◦ v souboru je přesný binární obraz zapisovaných dat◦ vhodné pro ukládání vnitřních datových struktur◦ lidsky přímo nečitelné◦ typicky fread/fwrite, lze i getc/putc (přístup po bajtech)◦ fseek/ftell OK

Textové vs. binární soubory

Page 29: NPRG0 4 1 Programování v C++ Programování v C

FILE* fopen( const char* fname, const char* mode);int fclose( FILE* fp);int fprintf( FILE* fp, const char* format, ...);int getc( FILE* fp);int putc( int c, FILE* fp);char* fgets( char* buffer, size_t limit, FILE* fp);int fputs( const char* buffer, FILE* fp);

size_t fread( void* ptr, size_t size, size_t n, FILE* fp);size_t fwrite( const void* ptr, size_t size, size_t n, FILE* fp);long ftell( FILE* fp);int fseek( FILE* fp, long offset, int whence);

whence: SEEK_SET, SEEK_CUR, SEEK_END

int fflush( FILE *fp);

Funkce pro práci se soubory

Page 30: NPRG0 4 1 Programování v C++ Programování v C

funkce pro práci se standardním vstupem/výstupem int getchar( void); int putchar( int c); int printf( const char* format, ...);

char* gets( char* buffer);

standardní vstup/výstupFILE* stand. otevřený na čtení/zápis před vstupem do main

FILE *stdin;FILE *stdout;

getchar() getc(stdin)putchar(c) putc(c, stdout)

FILE* fp = stdout;if( ...) fp = fopen( "...", "r");c = getc( fp);

Souborový vs. standardní v/v

jednotný zápisna std výstup nebo

do souboru

Nikdy nepoužívat!Nelze ohlídat přetečení bufferu

všechny souborové funkce lze použít

i pro std. v/v

Page 31: NPRG0 4 1 Programování v C++ Programování v C

<string.h> <cstring>strlen, strcmp, stricmp, strcpy, strncpy, strcat, strchr, strrchr, strstr,memset, memcmp, memcpy, memchr<stdio.h> <cstdio>getchar, putchar, fopen, tmpfile, fclose, getc, putc, fgets, fputs, freadfwrite, ftell, fseek, printf, fprintf, vfprintf, fflush, ungetcFILE, stdin, stdout, EOF, SEEK_SET, ...<stdlib.h> <cstdlib>malloc, free, atoi, atof, strtol, qsort, rand, exit<ctype.h> <cctype>isalpha, isdigit, isxdigit, isalnum, isspace, ispunct, iscntrl, islower,isupper, tolower, toupper<math.h> <cmath>abs, floor, sin, sqrt, exp, exp, log, ...<time.h> <ctime>

time, gmtime, strftime, asctime, clock, ...

Knihovní funkce C

... a mnoho dalších<assert.h> <errno.h><limits.h> <locale.h>

<stdarg.h> <setjmp.h>

C++ namespace std

Page 32: NPRG0 4 1 Programování v C++ Programování v C

#define _ F-->00||F-OO--;

int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()

{

_-_-_-_

_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_-_-_-_-_

_-_-_-_-_-_-_-_

_-_-_-_

}

Co (a proč ) dělá tento program?

Je v C, nikoliv v C++

Page 33: NPRG0 4 1 Programování v C++ Programování v C

přednáška: Bednárek, Yaghob, Zavoral◦ pokročilá a vybraná témata◦ pokročilá práce se šablonami, generické programování◦ konkurence a paralelismus◦ novinky C++11/14/17/TS◦ externí knihovny, ..., ...

cvičení - samostatná práce◦ 3 DÚ během semestru◦ zadání, vypracování, opravení, feedback◦ body ↠ známka

NPRG059 - Pokročilé praktikum z objektového programování◦ Mgr - povinný pro obor Softwarové systémy◦ doporučený pro SZZ okruhy SW inženýrství a Vývoj software◦ absolvování (Pokročilé C++ && (Pokročilá Java || Pokročilý C#))◦ + kvalitní sw projekt C++/C#/Java

Pokročilé programování v C++

Page 34: NPRG0 4 1 Programování v C++ Programování v C

vlastní C moduly◦ obj, lib, dll/so◦ jak linkovat C a C++ moduly ◦ jak dělat společné C/C++ headery

cizí C knihovny◦ jak z C++ volat C knihovny◦ callback z C knihoven do C++◦ mandlování, volací konvence◦ dynamicky linkované knihovny

Interoperabilita

Page 35: NPRG0 4 1 Programování v C++ Programování v C

Překlad více modulů

.c

.h .h

CC .obj Link .exe

.obj.obj.obj.obj.obj.lib

.obj.obj.obj

kompilace jednoho modulu

knihovnyknihovní headeryvlastní headery

.cpp

.c.cpp

další moduly

Page 36: NPRG0 4 1 Programování v C++ Programování v C

Vytvoření vlastní knihovny

.c

.h .h

CC .obj Lib .lib

.obj.obj.obj

kompilace jednoho modulu

knihovní headeryvlastní headery

.cpp

.c.cpp

další moduly

Page 37: NPRG0 4 1 Programování v C++ Programování v C

C++ exe / C lib

CPPC .obj Link .exe

.obj .lib

zdrojový text / překladač C

exe.cpp

lib.c

lib.h

CC Lib

zdrojový text / překladač C++

Page 38: NPRG0 4 1 Programování v C++ Programování v C

C++ exe / C lib

CPPC .obj Link .exe

.obj .lib

exe.cpp

lib.c

lib.h

CC Lib

error LNK2019: unresolved external symbol ◦ "int __cdecl lib_fnc(int)" (?lib_fnc@@YAHH@Z) ◦ referenced in function _main what the ... ...

hell???

Page 39: NPRG0 4 1 Programování v C++ Programování v C

mangling◦ mandlování◦ znetvoření◦ name-decoration

syntaktická a sémantická informace o symbolu◦ zjednoznačnění identifikátoru◦ proměnná / funkce / operator / metoda◦ typy a typové konstrukce parametrů a návratové hodnoty◦ třída, další atributy (const, volatile, ...)◦ volací konvence

formát jednotně nedefinovaný◦ závislý na platformě, překladači, ...◦ obecně nepřenositelné

Mandlování int a;int a( void);int a( int, int);class a {};class a { int a; };class a { int a( int); };

Page 40: NPRG0 4 1 Programování v C++ Programování v C

C++ exe / C lib

/* pureclib.c */#include "pureclib.h"

int lib_x;

int lib_fnc( int x){ return old_x;}

/* pureclib.h */

#ifndef PURECLIB__H_#define PURECLIB__H_

extern int lib_x;int lib_fnc( int x);

#endif

// cppexe.cpp#include "pureclib.h"

int main(....){ int i = lib_fnc( 1);}

CPPC CC různé překladačerůzné jazyky

různá implementace

_lib_fnc ?lib_fnc@@YAHH@Z

Page 41: NPRG0 4 1 Programování v C++ Programování v C

Společné hlavičkové soubory

/* pureclib.c */#include "pureclib.h"

int lib_x;

int lib_fnc( int x){ return old_x;}

/* pureclib.h */

#ifndef PURECLIB__H_#define PURECLIB__H_

#ifdef __cplusplusextern "C" {#endif

extern int lib_x;int lib_fnc( int x);

#ifdef __cplusplus}#endif

#endif

// cppexe.cpp#include "pureclib.h"

int main(....){ int i = lib_fnc( 1);}

CPPC CC

symboly C

_lib_fnc _lib_fncCPPC - definovanéCC - nedefinované

Page 42: NPRG0 4 1 Programování v C++ Programování v C

způsob implementace volání funkcí◦ registry vs. zásobník◦ zachovávání registrů◦ pořadí předávání parametrů◦ návratová hodnota◦ příprava a úklid zásobníku

konkrétní konvence◦ není součástí normy - rozšíření

__cdecl - default for C and C++, varargs __stdcall - Win32 API functions __fastcall - arguments in registers, faster __thiscall - this __clrcall - C++/CLI, .Net, managed code

Volací konvence

mov eax, 1mov ebx, 2call ?f@@X

mov eax, [ebp+08] mov ebx, [ebp+04]...

f( 1, 2);

Page 43: NPRG0 4 1 Programování v C++ Programování v C

C++ callback

/* pureclib.c */#include "pureclib.h"

int lib_cb( int x, int (*cb_fnc)( int)){ return cb_fnc( x);}

/* pureclib.h */

#ifdef __cplusplusextern "C" {#endif

int lib_cb( int x, int (*cb_fnc)( int));

#ifdef __cplusplus}#endif // cppexe.cpp

#include "pureclib.h"

extern "C" int cpp_fnc( int x) { return x+1;}

int main() { lib_cb( i, cpp_fnc);}

CC očekává C funkci

extern "C" určuje i volací konvenci

callbackknihovní kód volá klientskou funkci

CC očekává C funkci

Page 44: NPRG0 4 1 Programování v C++ Programování v C

použití funkcí dodaných až za běhu není součástí normy

◦ použití na různých platformách ideově podobné ale nepřenositelné

◦ pomocí preprocesoru lze multiplatformní rozhraní ale netriviální

Windows◦ .dll◦ chová se jako .exe◦ vlastní zásobník, heap, standardní knihovny

Linux / Unix◦ .so◦ chová se jako .lib◦ balíček .o

Dynamicky linkované knihovny

more details:

http://www.symantec.com/connect/articles/dynamic-linking-linux-and-windows-part-one

...-part-two

Page 45: NPRG0 4 1 Programování v C++ Programování v C

Dynamicky linkované knihovny// dll.cpp

extern "C" __declspec(dllexport)int add( int a, int b) { return a + b;}

BOOL APIENTRY DllMain(....) { return TRUE;}

// exe_explicit.cpp HINSTANCE dll = LoadLibrary( TEXT("dll.dll"));if( dll == NULL) return 1;

typedef int dll_fnc(int, int);dll_fnc* add = (dll_fnc*) GetProcAddress( dll, "add");if( add == NULL) { FreeLibrary( dll); return 1;}

int result = add(1, 2);

FreeLibrary( dll);

// exe_import.cpp extern "C" __declspec(dllimport)int add(int a, int b); int result = add(1, 2);

explicit runtime linking

běžné volání

statické slinkovánís dll.lib

jen proxy, kód v .dll

load dll