Вы находитесь на странице: 1из 8

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

9,931,592 members (50,155 online)

Sign in

home

articles

quick answers
o!to

discussions

features

community

help

Search for articles, questions, tips

Articles Languages C / C++ Language

6e8t

Article "ro!se Co#e Stats $e%isions (2) Alternati%es Comments & 'iscussions (1(()

o!)o9 :8+ort C++ classes -rom a 'LL


"/ Ale% &lekhman, 13 6o% 2012
(.91 (11F %otes)

About Article
)*e C++ +rogramming language an# ,in#o!s 'LLs can li%e in +eace a-ter all. )/+e Licence 0irst 1oste# 2ie!s Article CPOL 31 Aug 200 2!1"000 #"1#$ 32$ times

'ownload source ( 11)1 *&

Contents
4ntro#uction C Language A++roac* an#les Calling Con%entions :8ce+tion Sa-et/ A#%antages 'isa#%antages C++ 6ai%e A++roac*9 :8+orting a Class ,*at ;ou See 4s 6ot ,*at ;ou 7et :8ce+tion Sa-et/ A#%antages 'isa#%antages C++ <ature A++roac*9 =sing an Abstract 4nter-ace o! )*is ,or3s ,*/ )*is ,or3s ,it* >t*er Com+ilers =sing a Smart 1ointer :8ce+tion Sa-et/ A#%antages 'isa#%antages ,*at About S)L )em+late Classes? Summar/

'o!nloa#s "oo3mar3e#

C++ C++/CL4 C ,in#o!s 2isual5Stu#io 'e% , +

4ntro#uction
'/namic5Lin3 libraries ('LL) are an integrate# +art o- t*e ,in#o!s +lat-orm -rom its %er/ beginning. 'LLs allo! enca+sulation o- a +iece o- -unctionalit/ in a stan#alone mo#ule !it* an e8+licit list o- C -unctions t*at are a%ailable -or e8ternal users. 4n 19@0As, !*en ,in#o!s 'LLs !ere intro#uce# to t*e !orl#, t*e onl/ %iable o+tion to s+ea3 to broa# #e%elo+ment au#ience !as C language. So, naturall/, ,in#o!s 'LLs e8+ose# t*eir -unctionalit/ as C -unctions an# #ata. 4nternall/, a 'LL ma/ be im+lemente# in an/ language, but in or#er to be use# -rom ot*er languages an# en%ironments, a 'LL inter-ace s*oul# -all bac3 to t*e lo!est common #enominator B t*e C language. =sing t*e C inter-ace #oes not automaticall/ mean t*at a #e%elo+er s*oul# gi%e u+ obCect oriente# a++roac*. :%en t*e C inter-ace can be use# -or true obCect oriente# +rogramming, t*oug* it ma/ be a te#ious !a/ o- #oing t*ings. =nsur+risingl/, t*e secon# most use# +rogramming language in t*e !orl#, namel/ C++, coul# not *el+ but to -all +re/ to t*e tem+tation o- a 'LL. o!e%er, o++osite to t*e C language, !*ere t*e binar/ inter-ace bet!een a caller an# a callee is !ell5#e-ine# an# !i#el/ acce+te#, in t*e C++ !orl#, t*ere is no recogniDe# a++lication binar/ inter-ace (A"4). 4n +ractice, it means t*at binar/ co#e t*at is generate# b/ a C++ com+iler is not com+atible !it* ot*er C++ com+ilers. <oreo%er, t*e binar/ co#e o- t*e same C++ com+iler ma/ be incom+atible !it* ot*er %ersions o- t*is com+iler. All t*is ma3es e8+orting C++ classes -rom a 'LL Euite an a#%enture. )*e +ur+ose o- t*is article is to s*o! se%eral met*o#s o- e8+orting C++ classes -rom a 'LL mo#ule. )*e source co#e #emonstrates #i--erent tec*niEues o- e8+orting t*e imaginar/ Xyz obCect. )*e Xyz obCect is %er/ sim+le, an# *as onl/ one met*o#9 Foo. ere is t*e #iagram o- t*e obCect Xyz9 +y,
7et t*e 4nsi#er 6e!s -ree eac* morning.

)o+ 6e!s
S3ills t*at sel-5taug*t com+uter +rogrammers lac3

int Foo(int)
)*e im+lementation o- t*e Xyz obCect is insi#e a 'LL, !*ic* can be #istribute# to a !i#e range o- clients. A user can access Xyz -unctionalit/ b/9

$elate# 2i#eos

1 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

=sing +ure C =sing a regular C++ class =sing an abstract C++ inter-ace )*e source co#e consists o- t!o +roCects9 +y,Li-rary B a 'LL librar/ +roCect +y,.%ecuta-le B a ,in32 console +rogram t*at uses IXyzLibrary.dllI )*e +y,Li-rary +roCect e8+orts its co#e !it* t*e -ollo!ing *an#/ macro9
Colla+se J Co+/ Co#e

#if defined(XYZLIBRARY_EXPORT) // inside DLL # define XYZAPI __declspec(dlle po!t) #else // outside DLL # define XYZAPI __declspec(dlli"po!t) #endif // XYZLIBRARY_EXPORT

)*e XYZLIBRARY_EXPORT s/mbol is #e-ine# onl/ -or t*e +y,Li-rary +roCect, so t*e XYZAPI macro e8+an#s into __declspec(dlle po!t) -or t*e 'LL buil# an# into __declspec(dlli"po!t) -or t*e client buil#.

$elate# Articles
:8+orting C++ Classes -rom an <0C :8tension 'LL 0irst 7ui#e to <:0 an# Sil%erlig*t (1art 444) $egular 'LL )utor 0or "eginners

C Language A++roac*
an#les
)*e classic C language a++roac* to obCect oriente# +rogramming is t*e usage o- o+aEue +ointers, i.e., *an#les. A user calls a -unction t*at creates an obCect internall/, an# returns a *an#le to t*at obCect. )*en, t*e user calls %arious -unctions t*at acce+t t*e *an#le as a +arameter an# +er-orms all 3in#s o- o+erations on t*e obCect. A goo# e8am+le o- t*e *an#le usage is t*e ,in32 !in#o!ing A14 t*at uses an #$%& *an#le to re+resent a !in#o!. )*e imaginar/ Xyz obCect is e8+orte# %ia a C inter-ace, li3e t*is9
Colla+se J Co+/ Co#e

=sing classes e8+orte# -rom a 'LL using Loa#Librar/ 'LLs are sim+le9 1art 2 o! to use 6=nit to test nati%e C++ co#e CG class librar/ -or e8+orting #ata to CS2/:8cel -ile Creating 4m+ort Librar/ -rom a 'LL !it* ea#er 0ile =sing one e8tension 'LL in anot*er Ste+ b/ Ste+9 Calling C++ 'LLs -rom 2C++ an# 2" 5 1art 1 <inimiDe t*e 1ossibilit/ o- 'ata Corru+tion !*en :8+orting a Class 'll )i+s 1rogrammaticall/ a##ing attac*ments to emails in CG an# 2".6:) Ste+ b/ Ste+9 Calling C++ 'LLs -rom 2C++ an# 2" 5 1art 2 o! to create .lib -ile !*en /ou onl/ *a%e .#ll an# .* -iles Le%el'" 'LL -or ,in#o!s 5 A 6e! A++roac* to :8+orting C++ Classes -rom a 'LL '/namic 'LL Loa#ing List :8+orte# 0unctions o- 'LL A class to !ra+ 'LL -unctions An <0C e8tension librar/ to enable 'LL +lug5in tec*nolog/ -or /our a++lication using <:SSA7:H<A1s

typedef t'(XYZ#A%&LE )* + XYZ#A%&LE, // Factory function that creates instances of the Xy XYZAPI XYZ#A%&LE APIE%TRY -etXyz(.OI&), // $a%%s Xy #Foo &ethod# XYZAPI I%T APIE%TRY XyzFoo(XYZ#A%&LE /'ndle0 I%T n), // Re%eases Xy instance and frees resources# XYZAPI .OI& APIE%TRY XyzRele'se(XYZ#A%&LE /'ndle), // APIE'TRY is defined as __stdca%% in (inDef#h header# o!"ect#

ere is an e8am+le o- *o! a clientKs C co#e mig*t loo3 li3e9


Colla+se J Co+/ Co#e

#incl1de 2XyzLi3!'!y4/2 444 /) $reate Xy instance# )/ XYZ#A%&LE /Xyz 5 -etXyz(), if(/Xyz) ) /) $a%% Xy #Foo &ethod# )/ XyzFoo(/Xyz0 67), /) Destroy Xy instance and re%ease ac*uired resources# )/ XyzRele'se(/Xyz), /) Be defensi+e# )/ /Xyz 5 %8LL, *

,it* t*is a++roac*, a 'LL must +ro%i#e e8+licit -unctions -or obCect creation an# #eletion.

Calling Con%entions
4t is im+ortant to remember to s+eci-/ t*e calling con%ention -or all e8+orte# -unctions. >mitte# calling con%ention is a %er/ common mista3e t*at man/ beginners #o. As long as t*e #e-ault clientKs calling con%ention matc*es t*at ot*e 'LL, e%er/t*ing !or3s. "ut, once t*e client c*anges its calling con%ention, it goes unnotice# b/ t*e #e%elo+er until runtime cras*es occur. )*e +y,Li-rary +roCect uses t*e APIE%TRY macro, !*ic* is #e-ine# as __stdc'll in t*e IWinDef.hI *ea#er -ile.

:8ce+tion Sa-et/
6o C++ e8ce+tion is allo!e# to cross o%er t*e 'LL boun#ar/. 1erio#. )*e C language 3no!s not*ing about C++ e8ce+tions, an# cannot *an#le t*em +ro+erl/. 4- an obCect met*o# nee#s to re+ort an error, t*en a return co#e s*oul# be use#.

A#%antages
A 'LL can be use# b/ t*e !i#est +rogramming au#ience +ossible. Almost e%er/ mo#ern +rogramming language su++orts intero+erabilit/ !it* +lain C -unctions.

2 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

C run5time libraries o- a 'LL an# a client are in#e+en#ent o- eac* ot*er. Since resource acEuisition an# -reeing *a++ens entirel/ insi#e a 'LL mo#ule, a client is not a--ecte# b/ a 'LLKs c*oice o- C$).

'isa#%antages
)*e res+onsibilit/ o- calling t*e rig*t met*o#s on t*e rig*t instance o- an obCect rests on t*e user o- a 'LL. 0or e8am+le, in t*e -ollo!ing co#e sni++et, t*e com+iler !onKt be able to catc* t*e error9
Colla+se J Co+/ Co#e

/) +oid) ,et-o&eOtherO!"ect.+oid/ is dec%ared e%se0here# )/ XYZ#A%&LE / 5 -et9o"eOt/e!O3:ect(), /) Oo1s2 Error3 $a%%in4 Xy #Foo on 0ron4 o!"ect intance# )/ XyzFoo(/0 67),

:8+licit -unction calls are reEuire# in or#er to create an# #estro/ obCect instances. )*is is es+eciall/ anno/ing -or #eletion o- an instance. )*e client -unction must meticulousl/ insert a call to XyzRele'se at all +oints oe8it -rom a -unction. 4- t*e #e%elo+er -orgets to call XyzRele'se, t*en resources are lea3e# because t*e com+iler #oesnKt *el+ to trac3 t*e li-etime o- an obCect instance. 1rogramming languages t*at su++ort #estructors or *a%e a garbage collector ma/ mitigate t*is +roblem b/ ma3ing a !ra++er o%er t*e C inter-ace. 4- obCect met*o#s return or acce+t ot*er obCects as +arameters, t*en t*e 'LL aut*or *as to +ro%i#e a +ro+er C inter-ace -or t*ese obCects, too. )*e alternati%e is to -all bac3 to t*e lo!est common #enominator, t*at is t*e C language, an# use onl/ built5in t/+es (li3e int, do13le, c/'!+, etc.) as return t/+es an# met*o# +arameters.

C++ 6ai%e A++roac*9 :8+orting a Class


Almost e%er/ mo#ern C++ com+iler t*at e8ists on t*e ,in#o!s +lat-orm su++orts e8+orting a C++ class -rom a 'LL. :8+orting a C++ class is Euite similar to e8+orting C -unctions. All t*at a #e%elo+er is reEuire# to #o is to use t*e __declspec(dlle po!t;dlli"po!t) s+eci-ier be-ore t*e class name i- t*e !*ole class nee#s to be e8+orte#, or be-ore t*e met*o# #eclarations i- onl/ s+eci-ic class met*o#s nee# to be e8+orte#. ere is a co#e sni++et9
Colla+se J Co+/ Co#e

// The 0ho%e $Xy c%ass is e51orted 0ith a%% its &ethods and &e&!ers# // cl'ss XYZAPI <Xyz ) p13lic= int Foo(int n), *, // On%y $Xy 33Foo &ethod is e51orted# // cl'ss <Xyz ) p13lic= XYZAPI int Foo(int n), *,

)*ere is no nee# to e8+licitl/ s+eci-/ a calling con%ention -or e8+orting classes or t*eir met*o#s. "/ #e-ault, t*e C++ com+iler uses t*e __t/isc'll calling con%ention -or class met*o#s. o!e%er, #ue to #i--erent naming #ecoration sc*emes t*at are use# b/ #i--erent com+ilers, t*e e8+orte# C++ class can onl/ be use# b/ t*e same com+iler an# b/ t*e same %ersion o- t*e com+iler. ere is an e8am+le o- a naming #ecoration t*at is a++lie# b/ t*e <S 2isual C++ com+iler9

6otice *o! t*e #ecorate# names are #i--erent -rom t*e original C++ names. 0ollo!ing is a screens*ot o- t*e same 'LL mo#ule !it* name #ecoration #eci+*ere# b/ t*e 'e+en#enc/ ,al3er tool9

>nl/ t*e <S 2isual C++ com+iler can use t*is 'LL no!. "ot* t*e 'LL an# t*e client co#e must be com+ile# !it* t*e same %ersion o- <S 2isual C++ in or#er to ensure t*at t*e naming #ecoration sc*eme matc*es bet!een t*e caller an# t*e callee. ere is an e8am+le o- a client co#e t*at uses t*e Xyz obCect9
Colla+se J Co+/ Co#e

#incl1de 2XyzLi3!'!y4/2 444 // $%ient uses Xy <Xyz yz, yz4Foo(67),

o!"ect as a re4u%ar $66 c%ass#

As /ou can see, t*e usage o- an e8+orte# class is +rett/ muc* t*e same as t*e usage o- an/ ot*er C++ class. 6ot*ing s+ecial. /mportant0 =sing a 'LL t*at e8+orts C++ classes s*oul# be consi#ere# no #i--erent t*an using a static librar/. All rules t*at a++l/ to a static librar/ t*at contains C++ co#e are -ull/ a++licable to a 'LL t*at e8+orts C++ classes.

,*at ;ou See 4s 6ot ,*at ;ou 7et


A care-ul rea#er must *a%e alrea#/ notice# t*at t*e 'e+en#enc/ ,al3er tool s*o!es an a##itional e8+orte# member,

3 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

t*at is t*e <Xyz> <Xyz==ope!'to! 5(const <Xyz>) assignment o+erator. ,*at !e see is our C++ mone/ at !or3. Accor#ing to t*e C++ Stan#ar#, e%er/ class *as -our s+ecial member -unctions9 'e-ault constructor Co+/ constructor 'estructor Assignment o+erator (o+erator L) 4- t*e aut*or o- a class #oes not #eclare an# #oes not +ro%i#e an im+lementation o- t*ese members, t*en t*e C++ com+iler #eclares t*em, an# generates an im+licit #e-ault im+lementation. 4n t*e case o- t*e <Xyz class, t*e com+iler #eci#e# t*at t*e #e-ault constructor, co+/ constructor, an# t*e #estructor are tri%ial enoug*, an# o+timiDe# t*em out. o!e%er, t*e assignment o+erator sur%i%e# o+timiDation an# got e8+orte# -rom a 'LL. /mportant0 <ar3ing t*e class as e8+orte# !it* t*e __declspec(dlle po!t) s+eci-ier tells t*e com+iler to attem+t to e8+ort e%er/t*ing t*at is relate# to t*e class. 4t inclu#es all class #ata members, all class member -unctions (eit*er e8+licitl/ #eclare#, or im+licitl/ generate# b/ t*e com+iler), all base classes o- t*e class, an# all t*eir members. Consi#er9
Colla+se J Co+/ Co#e

cl'ss B'se ) 444 *, cl'ss &'t' ) 444 *, // 7- 8isua% $66 co&1i%er e&its $9:;< 0arnin4 a!out not e51orted !ase c%ass# cl'ss __declspec(dlle po!t) &e!i?ed = p13lic B'se ) 444 p!i?'te= &'t' "_d't', *,

// $9:<= 0arnin4 a!out not e51orted data &e&!er#

4n t*e abo%e co#e sni++et, t*e com+iler !ill !arn /ou about t*e not e8+orte# base class an# t*e not e8+orte# class ot*e #ata member. So, in or#er to e8+ort a C++ class success-ull/, a #e%elo+er is reEuire# to e8+ort all t*e rele%ant base classes an# all t*e classes t*at are use# -or t*e #e-inition o- t*e #ata members. )*is sno!ball e8+orting reEuirement is a signi-icant #ra!bac3. )*at is !*/, -or instance, it is %er/ *ar# an# tiresome to e8+ort classes t*at are #eri%e# -rom S)L tem+lates or to use S)L tem+lates as #ata members. An instantiation o- an S)L container li3e std=="'p@A, -or e8am+le, ma/ reEuire tens o- a##itional internal classes to be e8+orte#.

:8ce+tion Sa-et/
An e8+orte# C++ class ma/ t*ro! an e8ce+tion !it*out an/ +roblem. "ecause o- t*e -act t*at t*e same %ersion ot*e same C++ com+iler is use# bot* b/ a 'LL an# its client, C++ e8ce+tions are t*ro!n an# caug*t across 'LL boun#aries as i- t*ere !ere no boun#aries at all. $emember, using a 'LL t*at e8+orts C++ co#e is t*e same as using a static librar/ !it* t*e same co#e.

A#%antages
An e8+orte# C++ class can be use# in t*e same !a/ as an/ ot*er C++ class. An e8ce+tion t*at is t*ro!n insi#e a 'LL can be caug*t b/ t*e client !it*out an/ +roblem. ,*en onl/ small c*anges are ma#e in a 'LL mo#ule, no rebuil# is reEuire# -or ot*er mo#ules. )*is can be %er/ bene-icial -or big +roCects !*ere *uge amounts o- co#e are in%ol%e#. Se+arating logical mo#ules in a big +roCect into 'LL mo#ules ma/ be seen as t*e -irst ste+ to!ar#s true mo#ule se+aration. >%erall, it is a re!ar#ing acti%it/ t*at im+ro%es t*e mo#ularit/ o- a +roCect.

'isa#%antages
:8+orting C++ classes -rom a 'LL #oes not +re%ent %er/ tig*t cou+ling bet!een an obCect an# its user. )*e 'LL s*oul# be seen as a static librar/ !it* res+ect to co#e #e+en#encies. "ot* client co#e an# a 'LL must lin3 #/namicall/ !it* t*e same %ersion o- C$). 4t is necessar/ in or#er to enable correct boo33ee+ing o- C$) resources bet!een t*e mo#ules. 4- a client an# 'LL lin3 to #i--erent %ersions o- C$), or lin3 !it* C$) staticall/, t*en resources t*at *a%e been acEuire# in one instance o- t*e C$) !ill *a%e been -ree# in a #i--erent instance o- t*e C$). 4t !ill corru+t t*e internal state o- t*e C$) instance t*at attem+ts to o+erate on -oreign resources, an# most li3el/ !ill lea# to cras*. "ot* t*e client co#e an# t*e 'LL must agree on t*e e8ce+tion *an#ling/+ro+agating mo#el, an# use t*e same com+iler settings !it* res+ect to C++ e8ce+tions. :8+orting a C++ class reEuires e8+orting e%er/t*ing t*at is relate# to t*is class9 all its base classes, all classes t*at are use# -or t*e #e-inition o- #ata members, etc.

C++ <ature A++roac*9 =sing an Abstract 4nter-ace


A C++ abstract inter-ace (i.e., a C++ class t*at contains onl/ +ure %irtual met*o#s an# no #ata members) tries to get t*e best o- bot* !orl#s9 a com+iler in#e+en#ent clean inter-ace to an obCect, an# a con%enient obCect oriente# !a/ omet*o# calls. All t*at is reEuire# to #o is to +ro%i#e a *ea#er -ile !it* an inter-ace #eclaration an# im+lement a -actor/ -unction t*at !ill return t*e ne!l/ create# obCect instances. >nl/ t*e -actor/ -unction *as to be #eclare# !it*

4 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

t*e __declspec(dlle po!t;dlli"po!t) s+eci-ier. )*e inter-ace #oes not reEuire an/ a##itional s+eci-iers.
Colla+se J Co+/ Co#e

// The a!stract interface for Xy // 'o e5tra s1ecifiers re*uired# st!1ct IXyz ) ?i!t1'l int Foo(int n) 5 B, ?i!t1'l ?oid Rele'se() 5 B, *,

o!"ect#

// Factory function that creates instances of the Xy e te!n 2<2 XYZAPI IXyz+ APIE%TRY -etXyz(),

o!"ect#

4n t*e abo%e co#e sni++et, t*e -actor/ -unction -etXyz is #eclare# as e te!n 2<2. 4t is reEuire# in or#er to +re%ent t*e mangling o- t*e -unction name. So, t*is -unction is e8+ose# as a regular C -unction, an# can be easil/ recogniDe# b/ an/ C5com+atible com+iler. )*is is *o! t*e client co#e loo3s li3e, !*en using an abstract inter-ace9
Colla+se J Co+/ Co#e

#incl1de 2XyzLi3!'!y4/2 444 IXyz+ pXyz 5 ==-etXyz(), if(pXyz) ) pXyzCAFoo(67), pXyzCARele'se(), pXyz 5 %8LL, *

C++ #oes not +ro%i#e a s+ecial notion -or an inter-ace as ot*er +rogramming languages #o (-or e8am+le, CG or Ma%a). "ut it #oes not mean t*at C++ cannot #eclare an# im+lement inter-aces. )*e common a++roac* to ma3e a C++ inter-ace is to #eclare an abstract class !it*out an/ #ata members. )*en, anot*er se+arate class in*erits -rom t*e inter-ace an# im+lements inter-ace met*o#s, but t*e im+lementation is *i##en -rom t*e inter-ace clients. )*e inter-ace client neit*er 3no!s nor cares about *o! t*e inter-ace is im+lemente#. All it 3no!s is !*ic* met*o#s are a%ailable an# !*at t*e/ #o.

o! )*is ,or3s
)*e i#ea be*in# t*is a++roac* is %er/ sim+le. A member5less C++ class t*at consisting o- +ure %irtual met*o#s onl/ is not*ing more t*an a %irtual table, i.e., an arra/ o- -unction +ointers. )*is arra/ o- -unction +ointers is -ille# !it*in a 'LL !it* !*ate%er an aut*or #eems necessar/ to -ill. )*en, t*is arra/ o- +ointers is use# outsi#e o- a 'LL to call t*e actual im+lementation. "ello! is t*e #iagram t*at illustrates t*e IXyz inter-ace usage. Clic3 on t*e image to %ie! t*e -ull siDe# #iagram in a ne! !in#o!9

)*e abo%e #iagram s*o!s t*e IXyz inter-ace t*at is use# bot* b/ t*e 'LL an# t*e :N: mo#ules. 4nsi#e t*e 'LL mo#ule, t*e XyzI"pl class in*erits -rom t*e IXyz inter-ace, an# im+lements its met*o#s. <et*o# calls in t*e :N: mo#ule in%o3e t*e actual im+lementation in t*e 'LL mo#ule %ia a %irtual table.

,*/ )*is ,or3s ,it* >t*er Com+ilers


)*e s*ort e8+lanation is9 because C>< tec*nolog/ !or3s !it* ot*er com+ilers. 6o!, -or t*e long e8+lanation. Actuall/, using a member5less abstract class as an inter-ace bet!een mo#ules is e8actl/ !*at C>< #oes in or#er to e8+ose C>< inter-aces. )*e notion o- a %irtual table, as !e 3no! it in t*e C++ language, -its nicel/ into t*e s+eci-ication o- t*e C>< stan#ar#. )*is is not a coinci#ence. )*e C++ language, being t*e mainstream #e%elo+ment language -or at least o%er a #eca#e no!, *as been use# e8tensi%el/ !it* C>< +rogramming. 4t is t*an3s to natural su++ort -or obCect oriente# +rogramming in t*e C++ language. 4t is not sur+rising at all t*at <icroso-t *as consi#ere#

5 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

t*e C++ language as t*e main *ea%/5#ut/ instrument -or in#ustrial C>< #e%elo+ment. "eing t*e o!ner o- t*e C>< tec*nolog/, <icroso-t *as ensure# t*at t*e C>< binar/ stan#ar# an# t*eir o!n C++ obCect mo#el im+lementation in t*e 2isual C++ com+iler #o matc*, !it* as little o%er*ea# as +ossible. 6o !on#er t*at ot*er C++ com+iler %en#ors Cum+e# on t*e ban#!agon an# im+lemente# t*e %irtual table la/out in t*eir com+ilers in t*e same !a/ as <icroso-t #i#. A-ter all, e%er/bo#/ !ante# to su++ort C>< tec*nolog/, an# to be com+atible !it* t*e e8isting solution -rom <icroso-t. A */+ot*etical C++ com+iler t*at -ails to su++ort C>< e--icientl/ is #oome# to obli%ion in t*e ,in#o!s mar3et. )*at is !*/ ,no!a#a/s, e8+osing a C++ class -rom a 'LL %ia an abstract inter-ace !ill !or3 reliabl/ !it* e%er/ #ecent C++ com+iler on t*e ,in#o!s +lat-orm.

=sing a Smart 1ointer


4n or#er to ensure +ro+er resource release, an abstract inter-ace +ro%i#es an a##itional met*o# -or t*e #is+osal o- an instance. Calling t*is met*o# manuall/ can be te#ious an# error +rone. ,e all 3no! *o! common t*is error is in t*e C !orl# !*ere t*e #e%elo+er *as to remember to -ree t*e resources !it* an e8+licit -unction call. )*atKs !*/ t/+ical C++ co#e uses $A44 i#iom generousl/ !it* t*e *el+ o- smart +ointers. )*e +y,.%ecuta-le +roCect uses t*e A1to<losePt! tem+late, !*ic* is +ro%i#e# !it* t*e e8am+le. )*e A1to<losePt! tem+late is t*e sim+lest im+lementation o- a smart +ointer t*at calls an arbitrar/ met*o# o- a class to #estro/ an instance instea# oope!'to! delete. ere is a co#e sni++et t*at #emonstrates t*e usage o- a smart +ointer !it* t*e IXyz inter-ace9
Colla+se J Co+/ Co#e

#incl1de 2XyzLi3!'!y4/2 #incl1de 2A1to<losePt!4/2 444 typedef A1to<losePt!@IXyz0 ?oid0 >IXyz==Rele'seA IXyzPt!, IXyzPt! pt!Xyz(==-etXyz()), if(pt!Xyz) ) pt!XyzCAFoo(67), * // 'o need to ca%% 1trXy >?Re%ease./# -&art 1ointer // 0i%% ca%% this &ethod auto&atica%%y in the destructor#

=sing a smart +ointer !ill ensure t*at t*e Xyz obCect is +ro+erl/ release#, no matter !*at. A -unction can e8it +rematurel/ because o- an error or an internal e8ce+tion, but t*e C++ language guarantees t*at #estructors o- all local obCects !ill be calle# u+on t*e e8it.

1sing 2tandard C33 2mart Pointers


$ecent %ersions o- <S 2isual C++ +ro%i#e smart +ointers !it* t*e Stan#ar# C++ librar/. ere is t*e e8am+le o- using Xyz obCect !it* std==s/'!ed_pt! class9
Colla+se J Co+/ Co#e

#incl1de 2XyzLi3!'!y4/2 #incl1de @"e"o!yA #incl1de @f1nction'lA 444 typedef std==s/'!ed_pt!@IXyzA IXyzPt!, IXyzPt! pt!Xyz(==-etXyz()0 std=="e"_fn(>IXyz==Rele'se)), if(pt!Xyz) ) pt!XyzCAFoo(67), * // 'o need to ca%% 1trXy >?Re%ease./# std33shared_1tr c%ass // 0i%% ca%% this &ethod auto&atica%%y in its destructor#

:8ce+tion Sa-et/
4n t*e same !a/ as a C>< inter-ace is not allo!e# to lea3 an/ internal e8ce+tion, t*e abstract C++ inter-ace cannot let an/ internal e8ce+tion to brea3 t*roug* 'LL boun#aries. Class met*o#s s*oul# use return co#es to in#icate an error. )*e im+lementation -or *an#ling C++ e8ce+tions is %er/ s+eci-ic to eac* com+iler, an# cannot be s*are#. So, in t*is res+ect, an abstract C++ inter-ace s*oul# be*a%e as a +lain C -unction.

A#%antages
An e8+orte# C++ class can be use# %ia an abstract inter-ace, !it* an/ C++ com+iler. C run5time libraries o- a 'LL an# a client are in#e+en#ent o- eac* ot*er. Since resource acEuisition an# -reeing *a++ens entirel/ insi#e a 'LL mo#ule, a client is not a--ecte# b/ a 'LLKs c*oice o- C$). )rue mo#ule se+aration is ac*ie%e#. )*e resulting 'LL mo#ule can be re#esigne# an# rebuilt !it*out a--ecting t*e rest o- t*e +roCect. A 'LL mo#ule can be easil/ con%erte# to a -ull5-le#ge# C>< mo#ule, i- reEuire#.

'isa#%antages
An e8+licit -unction call is reEuire# to create a ne! obCect instance an# to #elete it. A smart +ointer can s+are a #e%elo+er o- t*e latter call, t*oug*.

6 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

An abstract inter-ace met*o# cannot return or acce+t a regular C++ obCect as a +arameter. 4t *as be eit*er a built5in t/+e (li3e int, do13le, c/'!+, etc.) or anot*er abstract inter-ace. 4t is t*e same limitation as -or C>< inter-aces.

,*at About S)L )em+late Classes?


)*e Stan#ar# C++ Librar/ containers (li3e ?ecto!, list, or "'p) an# ot*er tem+lates !ere not #esigne# !it* 'LL mo#ules in min#. )*e C++ Stan#ar# is silent about 'LLs because t*is is a +lat-orm s+eci-ic tec*nolog/, an# it is not necessaril/ +resent on ot*er +lat-orms !*ere t*e C++ language is use#. Currentl/, t*e <S 2isual C++ com+iler can e8+ort an# im+ort instantiations o- S)L classes !*ic* a #e%elo+er e8+licitl/ mar3s !it* t*e __declspec(dlle po!t;dlli"po!t) s+eci-ier. )*e com+iler emits a cou+le o- nast/ !arnings, but it !or3s. o!e%er, one must remember t*at e8+orting S)L tem+late instantiations is in no !a/ #i--erent -rom e8+orting regular C++ classes, !it* all accom+an/ing limitations. So, t*ere is not*ing s+ecial about S)L in t*at res+ect.

Summar/
)*e article #iscusse# #i--erent met*o#s o- e8+orting a C++ obCect -rom a 'LL mo#ule. 'etaile# #escri+tion is gi%en ot*e a#%antages an# #isa#%antages -or eac* met*o#. :8ce+tion sa-et/ consi#erations are outline#. )*e -ollo!ing conclusions are ma#e9 :8+orting an obCect as a set o- +lain C -unctions *as an a#%antage o- being com+atible !it* t*e !i#est range o- #e%elo+ment en%ironments an# +rogramming languages. o!e%er, a 'LL user is reEuire# to use out#ate# C tec*niEues or to +ro%i#e a##itional !ra++ers o%er t*e C inter-ace in or#er to use mo#ern +rogramming +ara#igms. :8+orting a regular C++ class is no #i--erent t*an +ro%i#ing a se+arate static librar/ !it* t*e C++ co#e. )*e usage is %er/ sim+le an# -amiliarO *o!e%er, t*ere is a tig*t cou+ling bet!een t*e 'LL an# its client. )*e same %ersion o- t*e same C++ com+iler must be use#, bot* -or t*e 'LL an# its client. 'eclaring an abstract member5less class an# im+lementing it insi#e a 'LL mo#ule is t*e best a++roac* to e8+ort C++ obCects, so -ar. )*is met*o# +ro%i#es a clean, !ell5#e-ine# obCect oriente# inter-ace bet!een t*e 'LL an# its client. Suc* a 'LL can be use# !it* an/ mo#ern C++ com+iler on t*e ,in#o!s +lat-orm. )*e usage o- an inter-ace in conCunction !it* smart +ointers is almost as eas/ as t*e usage o- an e8+orte# C++ class. )*e C++ +rogramming language is a +o!er-ul, %ersatile, an# -le8ible #e%elo+ment instrument.

License
)*is article, along !it* an/ associate# source co#e an# -iles, is license# un#er )*e Co#e 1roCect >+en License (C1>L)

About t*e Aut*or

Ale% &lekhman
So-t!are 'e%elo+er Australia <ore t*an ten /ears o- C++ nati%e #e%elo+ment, an# counting.

Article )o+
7 Tweet 28

Sign =+ to %ote Poor

Excellent

Vote

7 of 8

19/06/2013 17:54

HowTo: Export C++ classes from a DLL - CodeProject

http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-...

Comments an# 'iscussions


4ou must 2ign /n to use this message -oard) 2earch this forum 1ro-ile +o+u+s S+acing Relaxed 6oise Medium La/out Normal 1er +age 25 Go Update

0irst 1re% 6e8t

>y 5ote of # @ery simple and clear e%planation Aell doneB $e9 ,ell #oneS >y 5ote of # >y 5ote of # 2mall changes in a 'LL module $e9 Small c*anges in a 'LL mo#ule $e9 Small c*anges in a 'LL mo#ule Ahy to use e%tern CCC in C33 li-raryD $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? Tmo#i-ie#U $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? $e9 ,*/ to use e8tern ICI in C++ librar/? >y 5ote of # >y 5ote of : >y 5ote of # A-stract /nterface EmodifiedF $e9 Abstract 4nter-ace $e9 Abstract 4nter-ace +9: &uild
Last 2isit9 315'ec599 1@900 Last =+#ate9 195Mun513 09(9

A5iad P) skhan5ilkar7hpiinc)com sm8ones(home Ale8 "le3*man ;ikoder *<os/=3000 2amuele Ale8 "le3*man Samuele 'usan Paulo5ic Ale8 "le3*man 'usan 1aulo%ic 'usan 1aulo%ic Ale8 "le3*man 'usan 1aulo%ic Ale8 "le3*man 'usan 1aulo%ic Ale8 "le3*man >em-er $:19:33 >ehul 'onga magicpapacy Andy &antly Ale8 "le3*man An#/ "antl/ 4olanda >a%well $e-res*

(6un(13 0#! 2(6un(13 2022 2#(Apr(13 90:3 255A+r513 1291F 20(Apr(13 !0#2 12(>ar(13 031 22(?e-(13 301! 2250eb513 12923 2(50eb513 2093P #(?e-(13 20:9 2250eb513 12929 2350eb513 5935 2350eb513 F913 2350eb513 12900 2350eb513 22910 2350eb513 2293@ 2(50eb513 39(5 2(50eb513 1093P 20('ec(12 1 003 13('ec(12 000# 2('ec(12 20002 1:(;o5(12 9033 1(56o%512 1293@ 1556o%512 10935 13(;o5(12 !032 1 2 3 ( 5 P 6e8t

7eneral

6e!s

Suggestion

Ruestion

"ug

Ans!er

Mo3e

$ant

A#min

=se Ctrl+Le-t/$ig*t to s!itc* messages, Ctrl+=+/'o!n to s!itc* t*rea#s, Ctrl+S*i-t+Le-t/$ig*t to s!itc* +ages.
1ermalin3 J A#%ertise J 1ri%ac/ J <obile ,eb02 J 2.P.130P1F.1 J Last =+#ate# 13 6o% 2012 La/out9 -i8e# J -lui# Article Co+/rig*t 200@ b/ Ale8 "le3*man :%er/t*ing else Co+/rig*t Q Co#e1roCect, 199952013 )erms o- =se

8 of 8

19/06/2013 17:54

Вам также может понравиться