From d6462287cc0d657cf053f1484ee50e08d7a12b29 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 27 Sep 2009 11:00:45 +0200 Subject: added some C++ DLL windows documentation --- docs/libraries/howto_export_cpp_classes.txt | 1610 +++++++++++++++++++++++++++ 1 file changed, 1610 insertions(+) create mode 100644 docs/libraries/howto_export_cpp_classes.txt (limited to 'docs') diff --git a/docs/libraries/howto_export_cpp_classes.txt b/docs/libraries/howto_export_cpp_classes.txt new file mode 100644 index 0000000..9c531d3 --- /dev/null +++ b/docs/libraries/howto_export_cpp_classes.txt @@ -0,0 +1,1610 @@ + #[1]CodeProject Latest articles - All topics [2]CodeProject Latest + articles - MFC / C++ [3]CodeProject Latest articles - C# [4]CodeProject + Latest articles - ASP.NET [5]CodeProject Latest articles - .NET + [6]CodeProject Latest articles - VB.NET [7]CodeProject Lounge Postings + [8]CodeProject + + [9]Click here to Skip to main content + + 6,491,710 members and growing! (15,072 online) + Email ____________________ Password ____________________ Sign in [_] + Remember me? [10]help Lost your password? + [11]The Code Project + * [12]Home + * [13]Articles + + [14]Search + + [15]Latest Articles + + [16]Top Articles + + [17]Beginner Articles + + [18]Technical Blogs + + [19]Post an Article + + + + [20]Post your Blog + + [21]Posting/Update Guidelines + + [22]Article Competition + + [23]Topic List + * [24]Message Boards + + [25]ASP.NET + + [26]ATL / WTL / STL + + [27]C / C++ / MFC + + [28]Managed C++/CLI + + [29]C# + + [30]COM + + [31]Hardware & Devices + + [32]LINQ + + [33].NET Framework + + [34]System Admin + + [35]Silverlight + + [36]General Database + + [37]Sharepoint + + [38]Visual Basic + + [39]Web Development + + [40]WPF / WCF / WF + + [41]XML / XSL + + [42]General IT Issues + + [43]Site Bugs / Suggestions + + [44]The Soapbox 2.0 + + [45]All Message Boards... + * [46]Job Board + + [47]Latest + + [48]Search + + [49]Post a Job + + [50]FAQ and Pricing + * [51]Catalog + + [52]Latest + + [53]Search + + [54]Post a Catalog Item + + [55]FAQ and Pricing + * [56]Help! + + [57]What is 'The Code Project'? + + [58]General FAQ + + [59]Post a Question + + [60]Site Directory + + [61]About Us + * [62]Lounge [63]Soapbox + + [64]Languages » [65]C / C++ Language » [66]Howto Beginner License: + [67]The Code Project Open License (CPOL) + +HowTo: Export C++ classes from a DLL + + By [68]Alex Blekhman + The C++ programming language and Windows DLLs can live in peace after + all. C++ (VC6, VC7, VC7.1, VC8.0), C++/CLI, C, Windows, Dev + Posted: 31 Aug 2008 + Views: 40,912 + Bookmarked: 129 times + + Announcements + Comp [69]Monthly Competition + Loading... + Articles + [70]Desktop Development + [71]Button Controls + [72]Clipboard + [73]Combo & List Boxes + [74]Dialogs and Windows + [75]Desktop Gadgets + [76]Document / View + [77]Edit Controls + [78]Files and Folders + [79]Grid & Data Controls + [80]List Controls + [81]Menus + [82]Miscellaneous + [83]Printing + [84]Progress Controls + [85]Selection Controls + [86]Shell and IE programming + [87]Smart Client + [88]Splitter Windows + [89]Static & Panel Controls + [90]Status Bar + [91]Tabs & Property Pages + [92]Toolbars & Docking windows + [93]Tree Controls + [94]Web Development + [95]Ajax and Atlas + [96]Applications & Tools + [97]ASP + [98]ASP.NET + [99]ASP.NET Controls + [100]ATL Server + [101]Caching + [102]Charts, Graphs and Images + [103]Client side scripting + [104]Custom Controls + [105]HTML / CSS + [106]ISAPI + [107]Site & Server Management + [108]Session State + [109]Silverlight + [110]Trace and Logs + [111]User Controls + [112]Validation + [113]View State + [114]WAP / WML + [115]Web Security + [116]Web Services + [117]Enterprise Systems + [118]Content Management Server + [119]Microsoft BizTalk Server + [120]Microsoft Exchange + [121]Office Development + [122]SharePoint Server + [123]Multimedia + [124]Audio and Video + [125]DirectX + [126]GDI + [127]GDI+ + [128]General Graphics + [129]OpenGL + [130]Database + [131]Database + [132]SQL Reporting Services + [133]Platforms, Frameworks & Libraries + [134]ATL + [135]MFC + [136]STL + [137]WTL + [138]COM / COM+ + [139].NET Framework + [140]Win32/64 SDK & OS + [141]Vista API + [142]Vista Security + [143]Cross Platform + [144]Game Development + [145]Mobile Development + [146]Windows CardSpace + [147]Windows Communication Foundation + [148]Windows Presentation Foundation + [149]Windows Workflow Foundation + [150]Libraries + [151]Windows Powershell + [152]LINQ + [153]Languages + [154]C / C++ Language + [155]C++ / CLI + [156]C# + [157]MSIL + [158]VBScript + [159]VB.NET + [160]VB6 Interop + [161]Other .NET Languages + [162]XML + [163]Java + [164]General Programming + [165]Algorithms & Recipes + [166]Bugs & Workarounds + [167]Collections + [168]Cryptography & Security + [169]Date and Time + [170]DLLs & Assemblies + [171]Exception Handling + [172]Localisation + [173]Macros and Add-ins + [174]Programming Tips + [175]String handling + [176]Internet / Network + [177]Threads, Processes & IPC + [178]WinHelp / HTMLHelp + [179]Uncategorised FAQ Entries + [180]Graphics / Design + [181]Expression + [182]Usability + [183]Development Lifecycle + [184]Debug Tips + [185]Design and Architecture + [186]Installation + [187]Work Issues + [188]Testing and QA + [189]Code Generation + [190]General Reading + [191]Book Chapters + [192]Book Reviews + [193]Hardware Reviews + [194]Interviews + [195]Scrapbook + [196]Hardware & System + [197]Uncategorised Technical Blogs + [198]Author Resources + [199]Third Party Products + [200]Product Showcase + [201]Solution Center + [202]Mentor Resources + Services + [203]Product Catalog + [204]Code-signing Certificates + [205]Job Board + [206]CodeProject VS2008 Addin + Feature Zones + [207]Product Showcase + Search ____________________ [Articles.......] Go! + [208]Advanced Search + print [209]Print add [210]Share + Discuss [211]Discuss Broken Article? [212]Report + 55 votes for this article. + [red.gif] [red.gif] [red.gif] [red.gif] [red.gif] [white.gif] + [213]Popularity: 8.33 Rating: 4.79 out of 5 + 1 vote, 1.8% + 1 1 vote, 1.8% + 2 1 vote, 1.8% + 3 5 votes, 9.1% + 4 47 votes, 85.5% + 5 + * [214]Download source - 11.1 KB + +Contents + + * [215]Introduction + * [216]C Language Approach + + Handles + + Calling Conventions + + Exception Safety + + Advantages + + Disadvantages + * [217]C++ Naive Approach: Exporting a Class + + What You See Is Not What You Get + + Exception Safety + + Advantages + + Disadvantages + * [218]C++ Mature Approach: Using an Abstract Interface + + How This Works + + Why This Works With Other Compilers + + Using a Smart Pointer + + Exception Safety + + Advantages + + Disadvantages + * [219]What About STL Template Classes? + * [220]Summary + +Introduction + + Dynamic-Link libraries (DLL) are an integrated part of the Windows + platform from its very beginning. DLLs allow encapsulation of a piece + of functionality in a standalone module with an explicit list of C + functions that are available for external users. In 1980's, when + Windows DLLs were introduced to the world, the only viable option to + speak to broad development audience was C language. So, naturally, + Windows DLLs exposed their functionality as C functions and data. + Internally, a DLL may be implemented in any language, but in order to + be used from other languages and environments, a DLL interface should + fall back to the lowest common denominator - the C language. + + Using the C interface does not automatically mean that a developer + should give up object oriented approach. Even the C interface can be + used for true object oriented programming, though it may be a tedious + way of doing things. Unsurprisingly, the second most used programming + language in the world, namely C++, could not help but to fall prey to + the temptation of a DLL. However, opposite to the C language, where the + binary interface between a caller and a callee is well-defined and + widely accepted, in the C++ world, there is no recognized application + binary interface (ABI). In practice, it means that binary code that is + generated by a C++ compiler is not compatible with other C++ compilers. + Moreover, the binary code of the same C++ compiler may be incompatible + with other versions of this compiler. All this makes exporting C++ + classes from a DLL quite an adventure. + + The purpose of this article is to show several methods of exporting C++ + classes from a DLL module. The source code demonstrates different + techniques of exporting the imaginary Xyz object. The Xyz object is + very simple, and has only one method: Foo. + + Here is the diagram of the object Xyz: + Xyz + int Foo(int) + + The implementation of the Xyz object is inside a DLL, which can be + distributed to a wide range of clients. A user can access Xyz + functionality by: + * Using pure C + * Using a regular C++ class + * Using an abstract C++ interface + + The source code consists of two projects: + * XyzLibrary - a DLL library project + * XyzExecutable - a Win32 console program that uses "XyzLibrary.dll" + + The XyzLibrary project exports its code with the following handy macro: +#if defined(XYZLIBRARY_EXPORT) // inside DLL +# define XYZAPI __declspec(dllexport) +#else // outside DLL +# define XYZAPI __declspec(dllimport) +#endif // XYZLIBRARY_EXPORT + + The XYZLIBRARY_EXPORT symbol is defined only for the XyzLibrary + project, so the XYZAPI macro expands into __declspec(dllexport) for the + DLL build and into __declspec(dllimport) for the client build. + +C Language Approach + +Handles + + The classic C language approach to object oriented programming is the + usage of opaque pointers, i.e., handles. A user calls a function that + creates an object internally, and returns a handle to that object. + Then, the user calls various functions that accept the handle as a + parameter and performs all kinds of operations on the object. A good + example of the handle usage is the Win32 windowing API that uses an + HWND handle to represent a window. The imaginary Xyz object is exported + via a C interface, like this: +typedef tagXYZHANDLE {} * XYZHANDLE; + +// Factory function that creates instances of the Xyz object. +XYZAPI XYZHANDLE APIENTRY GetXyz(VOID); + +// Calls Xyz.Foo method. +XYZAPI INT APIENTRY XyzFoo(XYZHANDLE handle, INT n); +// Releases Xyz instance and frees resources. +XYZAPI VOID APIENTRY XyzRelease(XYZHANDLE handle); + +// APIENTRY is defined as __stdcall in WinDef.h header. + + Here is an example of how a client's C code might look like: +#include "XyzLibrary.h" + +... + +/* Create Xyz instance. */ +XYZHANDLE hXyz = GetXyz(); + +if(hXyz) +{ + /* Call Xyz.Foo method. */ + XyzFoo(hXyz, 42); + + /* Destroy Xyz instance and release acquired resources. */ + XyzRelease(hXyz); + + /* Be defensive. */ + hXyz = NULL; +} + + With this approach, a DLL must provide explicit functions for object + creation and deletion. + +Calling Conventions + + It is important to remember to specify the calling convention for all + exported functions. Omitted calling convention is a very common mistake + that many beginners do. As long as the default client's calling + convention matches that of the DLL, everything works. But, once the + client changes its calling convention, it goes unnoticed by the + developer until runtime crashes occur. The XyzLibrary project uses the + APIENTRY macro, which is defined as __stdcall in the "WinDef.h" header + file. + +Exception Safety + + No C++ exception is allowed to cross over the DLL boundary. Period. The + C language knows nothing about C++ exceptions, and cannot handle them + properly. If an object method needs to report an error, then a return + code should be used. + +Advantages + + * A DLL can be used by the widest programming audience possible. + Almost every modern programming language supports interoperability + with plain C functions. + * C run-time libraries of a DLL and a client are independent of each + other. Since resource acquisition and freeing happens entirely + inside a DLL module, a client is not affected by a DLL's choice of + CRT. + +Disadvantages + + * The responsibility of calling the right methods on the right + instance of an object rests on the user of a DLL. For example, in + the following code snippet, the compiler won't be able to catch the + error: +/* void* GetSomeOtherObject(void) is declared elsewhere. */ +XYZHANDLE h = GetSomeOtherObject(); + +/* Oops! Error: Calling Xyz.Foo on wrong object intance. */ +XyzFoo(h, 42); + * Explicit function calls are required in order to create and destroy + object instances. This is especially annoying for deletion of an + instance. The client function must meticulously insert a call to + XyzRelease at all points of exit from a function. If the developer + forgets to call XyzRelease, then resources are leaked because the + compiler doesn't help to track the lifetime of an object instance. + Programming languages that support destructors or have a garbage + collector may mitigate this problem by making a wrapper over the C + interface. + * If object methods return or accept other objects as parameters, + then the DLL author has to provide a proper C interface for these + objects, too. The alternative is to fall back to the lowest common + denominator, that is the C language, and use only built-in types + (like int, double, char*, etc.) as return types and method + parameters. + +C++ Naive Approach: Exporting a Class + + Almost every modern C++ compiler that exists on the Windows platform + supports exporting a C++ class from a DLL. Exporting a C++ class is + quite similar to exporting C functions. All that a developer is + required to do is to use the __declspec(dllexport/dllimport) specifier + before the class name if the whole class needs to be exported, or + before the method declarations if only specific class methods need to + be exported. Here is a code snippet: +// The whole CXyz class is exported with all its methods and members. +// +class XYZAPI CXyz +{ +public: + int Foo(int n); +}; + +// Only CXyz::Foo method is exported. +// +class CXyz +{ +public: + XYZAPI int Foo(int n); +}; + + There is no need to explicitly specify a calling convention for + exporting classes or their methods. By default, the C++ compiler uses + the __thiscall calling convention for class methods. However, due to + different naming decoration schemes that are used by different + compilers, the exported C++ class can only be used by the same compiler + and by the same version of the compiler. Here is an example of a naming + decoration that is applied by the MS Visual C++ compiler: + + C++ names are decorated or "mangled". + + Notice how the decorated names are different from the original C++ + names. Following is a screenshot of the same DLL module with name + decoration deciphered by the [221]Dependency Walker tool: + + C++ names are undecorated by Dependency Walker. + + Only the MS Visual C++ compiler can use this DLL now. Both the DLL and + the client code must be compiled with the same version of MS Visual C++ + in order to ensure that the naming decoration scheme matches between + the caller and the callee. Here is an example of a client code that + uses the Xyz object: +#include "XyzLibrary.h" + +... +// Client uses Xyz object as a regular C++ class. +CXyz xyz; +xyz.Foo(42); + + As you can see, the usage of an exported class is pretty much the same + as the usage of any other C++ class. Nothing special. + + Important: Using a DLL that exports C++ classes should be considered no + different than using a static library. All rules that apply to a static + library that contains C++ code are fully applicable to a DLL that + exports C++ classes. + +What You See Is Not What You Get + + A careful reader must have already noticed that the Dependency Walker + tool showes an additional exported member, that is the CXyz& + CXyz::operator =(const CXyz&) assignment operator. What we see is our + C++ money at work. According to the C++ Standard, every class has four + special member functions: + * Default constructor + * Copy constructor + * Destructor + * Assignment operator (operator =) + + If the author of a class does not declare and does not provide an + implementation of these members, then the C++ compiler declares them, + and generates an implicit default implementation. In the case of the + CXyz class, the compiler decided that the default constructor, copy + constructor, and the destructor are trivial enough, and optimized them + out. However, the assignment operator survived optimization and got + exported from a DLL. + + Important: Marking the class as exported with the __declspec(dllexport) + specifier tells the compiler to attempt to export everything that is + related to the class. It includes all class data members, all class + member functions (either explicitly declared, or implicitly generated + by the compiler), all base classes of the class, and all their members. + Consider: +class Base +{ + ... +}; + +class Data +{ + ... +}; + +// MS Visual C++ compiler emits C4275 warning about not exported base class. +class __declspec(dllexport) Derived : + public Base +{ + ... + +private: + Data m_data; // C4251 warning about not exported data member. +}; + + In the above code snippet, the compiler will warn you about the not + exported base class and the not exported class of the data member. So, + in order to export a C++ class successfully, a developer is required to + export all the relevant base classes and all the classes that are used + for the definition of the data members. This snowball exporting + requirement is a significant drawback. That is why, for instance, it is + very hard and tiresome to export classes that are derived from STL + templates or to use STL templates as data members. An instantiation of + an STL container like std::map<>, for example, may require tens of + additional internal classes to be exported. + +Exception Safety + + An exported C++ class may throw an exception without any problem. + Because of the fact that the same version of the same C++ compiler is + used both by a DLL and its client, C++ exceptions are thrown and caught + across DLL boundaries as if there were no boundaries at all. Remember, + using a DLL that exports C++ code is the same as using a static library + with the same code. + +Advantages + + * An exported C++ class can be used in the same way as any other C++ + class. + * An exception that is thrown inside a DLL can be caught by the + client without any problem. + * When only small changes are made in a DLL module, no rebuild is + required for other modules. This can be very beneficial for big + projects where huge amounts of code are involved. + * Separating logical modules in a big project into DLL modules may be + seen as the first step towards true module separation. Overall, it + is a rewarding activity that improves the modularity of a project. + +Disadvantages + + * Exporting C++ classes from a DLL does not prevent very tight + coupling between an object and its user. The DLL should be seen as + a static library with respect to code dependencies. + * Both client code and a DLL must link dynamically with the same + version of CRT. It is necessary in order to enable correct + bookkeeping of CRT resources between the modules. If a client and + DLL link to different versions of CRT, or link with CRT statically, + then resources that have been acquired in one instance of the CRT + will have been freed in a different instance of the CRT. It will + corrupt the internal state of the CRT instance that attempts to + operate on foreign resources, and most likely will lead to crash. + * Both the client code and the DLL must agree on the exception + handling/propagating model, and use the same compiler settings with + respect to C++ exceptions. + * Exporting a C++ class requires exporting everything that is related + to this class: all its base classes, all classes that are used for + the definition of data members, etc. + +C++ Mature Approach: Using an Abstract Interface + + A C++ abstract interface (i.e., a C++ class that contains only pure + virtual methods and no data members) tries to get the best of both + worlds: a compiler independent clean interface to an object, and a + convenient object oriented way of method calls. All that is required to + do is to provide a header file with an interface declaration and + implement a factory function that will return the newly created object + instances. Only the factory function has to be declared with the + __declspec(dllexport/dllimport) specifier. The interface does not + require any additional specifiers. +// The abstract interface for Xyz object. +// No extra specifiers required. +struct IXyz +{ + virtual int Foo(int n) = 0; + virtual void Release() = 0; +}; + +// Factory function that creates instances of the Xyz object. +extern "C" XYZAPI IXyz* APIENTRY GetXyz(); + + In the above code snippet, the factory function GetXyz is declared as + extern "C". It is required in order to prevent the mangling of the + function name. So, this function is exposed as a regular C function, + and can be easily recognized by any C-compatible compiler. This is how + the client code looks like, when using an abstract interface: +#include "XyzLibrary.h" + +... +IXyz* pXyz = ::GetXyz(); + +if(pXyz) +{ + pXyz->Foo(42); + + pXyz->Release(); + pXyz = NULL; +} + + C++ does not provide a special notion for an interface as other + programming languages do (for example, C# or Java). But it does not + mean that C++ cannot declare and implement interfaces. The common + approach to make a C++ interface is to declare an abstract class + without any data members. Then, another separate class inherits from + the interface and implements interface methods, but the implementation + is hidden from the interface clients. The interface client neither + knows nor cares about how the interface is implemented. All it knows is + which methods are available and what they do. + +How This Works + + The idea behind this approach is very simple. A member-less C++ class + that consisting of pure virtual methods only is nothing more than a + virtual table, i.e., an array of function pointers. This array of + function pointers is filled within a DLL with whatever an author deems + necessary to fill. Then, this array of pointers is used outside of a + DLL to call the actual implementation. Bellow is the diagram that + illustrates the IXyz interface usage. + + Click on the image to view the full sized diagram in a new window: + + [222]Using IXyz interface from the outside of a DLL + + The above diagram shows the IXyz interface that is used both by the DLL + and the EXE modules. Inside the DLL module, the XyzImpl class inherits + from the IXyz interface, and implements its methods. Method calls in + the EXE module invoke the actual implementation in the DLL module via a + virtual table. + +Why This Works With Other Compilers + + The short explanation is: because COM technology works with other + compilers. Now, for the long explanation. Actually, using a member-less + abstract class as an interface between modules is exactly what COM does + in order to expose COM interfaces. The notion of a virtual table, as we + know it in the C++ language, fits nicely into the specification of the + COM standard. This is not a coincidence. The C++ language, being the + mainstream development language for at least over a decade now, has + been used extensively with COM programming. It is thanks to natural + support for object oriented programming in the C++ language. It is not + surprising at all that Microsoft has considered the C++ language as the + main heavy-duty instrument for industrial COM development. Being the + owner of the COM technology, Microsoft has ensured that the COM binary + standard and their own C++ object model implementation in the Visual + C++ compiler do match, with as little overhead as possible. + + No wonder that other C++ compiler vendors jumped on the bandwagon and + implemented the virtual table layout in their compilers in the same way + as Microsoft did. After all, everybody wanted to support COM + technology, and to be compatible with the existing solution from + Microsoft. A hypothetical C++ compiler that fails to support COM + efficiently is doomed to oblivion in the Windows market. That is why + ,nowadays, exposing a C++ class from a DLL via an abstract interface + will work reliably with every decent C++ compiler on the Windows + platform. + +Using a Smart Pointer + + In order to ensure proper resource release, an abstract interface + provides an additional method for the disposal of an instance. Calling + this method manually can be tedious and error prone. We all know how + common this error is in the C world where the developer has to remember + to free the resources with an explicit function call. That's why + typical C++ code uses [223]RAII idiom generously with the help of smart + pointers. The XyzExecutable project uses the AutoClosePtr template, + which is provided with the example. The AutoClosePtr template is the + simplest implementation of a smart pointer that calls an arbitrary + method of a class to destroy an instance instead of operator delete. + Here is a code snippet that demonstrates the usage of a smart pointer + with the IXyz interface: +#include "XyzLibrary.h" +#include "AutoClosePtr.h" + +... +typedef AutoClosePtr IXyzPtr; + +IXyzPtr ptrXyz(::GetXyz()); + +if(ptrXyz) +{ + ptrXyz->Foo(42); +} + +// No need to call ptrXyz->Release(). Smart pointer +// will call this method automatically in the destructor. + + Using a smart pointer will ensure that the Xyz object is properly + released, no matter what. A function can exit prematurely because of an + error or an internal exception, but the C++ language guarantees that + destructors of all local objects will be called upon the exit. + +Exception Safety + + In the same way as a COM interface is not allowed to leak any internal + exception, the abstract C++ interface cannot let any internal exception + to break through DLL boundaries. Class methods should use return codes + to indicate an error. The implementation for handling C++ exceptions is + very specific to each compiler, and cannot be shared. So, in this + respect, an abstract C++ interface should behave as a plain C function. + +Advantages + + * An exported C++ class can be used via an abstract interface, with + any C++ compiler. + * C run-time libraries of a DLL and a client are independent of each + other. Since resource acquisition and freeing happens entirely + inside a DLL module, a client is not affected by a DLL's choice of + CRT. + * True module separation is achieved. The resulting DLL module can be + redesigned and rebuilt without affecting the rest of the project. + * A DLL module can be easily converted to a full-fledged COM module, + if required. + +Disadvantages + + * An explicit function call is required to create a new object + instance and to delete it. A smart pointer can spare a developer of + the latter call, though. + * An abstract interface method cannot return or accept a regular C++ + object as a parameter. It has be either a built-in type (like int, + double, char*, etc.) or another abstract interface. It is the same + limitation as for COM interfaces. + +What About STL Template Classes? + + The Standard C++ Library containers (like vector, list, or map) and + other templates were not designed with DLL modules in mind. The C++ + Standard is silent about DLLs because this is a platform specific + technology, and it is not necessarily present on other platforms where + the C++ language is used. Currently, the MS Visual C++ compiler can + export and import instantiations of STL classes which a developer + explicitly marks with the __declspec(dllexport/dllimport) specifier. + The compiler emits a couple of nasty warnings, but it works. However, + one must remember that exporting STL template instantiations is in no + way different from exporting regular C++ classes, with all accompanying + limitations. So, there is nothing special about STL in that respect. + +Summary + + The article discussed different methods of exporting a C++ object from + a DLL module. Detailed description is given of the advantages and + disadvantages for each method. Exception safety considerations are + outlined. The following conclusions are made: + * Exporting an object as a set of plain C functions has an advantage + of being compatible with the widest range of development + environments and programming languages. However, a DLL user is + required to use outdated C techniques or to provide additional + wrappers over the C interface in order to use modern programming + paradigms. + * Exporting a regular C++ class is no different than providing a + separate static library with the C++ code. The usage is very simple + and familiar; however, there is a tight coupling between the DLL + and its client. The same version of the same C++ compiler must be + used, both for the DLL and its client. + * Declaring an abstract member-less class and implementing it inside + a DLL module is the best approach to export C++ objects, so far. + This method provides a clean, well-defined object oriented + interface between the DLL and its client. Such a DLL can be used + with any modern C++ compiler on the Windows platform. The usage of + an interface in conjunction with smart pointers is almost as easy + as the usage of an exported C++ class. + + The C++ programming language is a powerful, versatile, and flexible + development instrument. + +License + + This article, along with any associated source code and files, is + licensed under [224]The Code Project Open License (CPOL) + +About the Author + + [225]Alex Blekhman + + [{5874ff19-35c6-4efd-9554-30f827a5475e}.png] + + Member + Occupation: Software Developer + Location: Israel Israel + +Other popular C / C++ Language articles: + + * [226]Member Function Pointers and the Fastest Possible C++ + Delegates + A comprehensive tutorial on member function pointers, and an + implementation of delegates that generates only two ASM opcodes! + * [227]How a C++ compiler implements exception handling + An indepth discussion of how VC++ implements exception handling. + Source code includes exception handling library for VC++. + * [228]A Beginner's Guide to Pointers + An article showing the use of pointers in C and C++ + * [229]XML class for processing and building simple XML documents + Link CMarkup into your VC++ app and avoid complex XML tools and + dependencies + * [230]PugXML - A Small, Pugnacious XML Parser + Discussion of techniques for fast, robust, light-weight XML + parsing. + + [231]Article Top + [232]Sign Up to vote for this article + Your reason for this vote: + ____________________________________________________________ + ____________________________________________________________ + ____________________________________________________________ + ____________________________________________________________ + ____________________________________________________________ + + IFRAME: [233]/script/Adm/ServeLinks.aspx?C=False&ids=10693,5226,8560 + + You must [234]Sign In to use this message board. + FAQ [235]FAQ ____________________ Search + + Noise Tolerance[Medium...] Layout[Expand Posts & Replies] Per + page[25] Update + + Msgs 1 to 25 of 42 (Total in Forum: 42) ([236]Refresh) + FirstPrev[237]Next + General [238]source file path in c++ [239]Pin member [240]JinXu 19:50 + 19 May '09 + Hi, Alex, + I use Visual Studio to generate my DLLs. But I find that c++ source + paths are often stored in the generated DLLs as strings, even in + release version. Frown Can you tell me why? + Thanks a lot! + Hello world! + [241]Sign In·[242]View Thread·[243]PermaLink + General [244]Re: source file path in c++ [245]Pin member [246]Alex + Blekhman 23:36 19 May '09 + I don't know why. This is the way MS linker builds executable modules. + However, you can select the .PDB file during debug session manually if + VC++ IDE doesn't find the one specified in the .EXE/.DLL module. + [247]Sign In·[248]View Thread·[249]PermaLink + General [250]Static library [251]Pin member [252]Osman Kevin 15:57 21 + Mar '09 + In my project, I want to eliminate the dependency of DLL, so I am + planning to use static library, does this method apply to the static + library as well ? + [253]Sign In·[254]View Thread·[255]PermaLink + General [256]Re: Static library [257]Pin member [258]Alex Blekhman 2:51 + 22 Mar '09 + If you want to use static library, then you don't need to worry about + DLL techniques at all. just compile your code as a .LIB, thne link with + it. That's all. + [259]Sign In·[260]View Thread·[261]PermaLink + General [262]calling convention for each method in abstract class is + required [263]Pin member [264]chipmunk 3:13 18 Feb '09 + Great article, thanks ! + But I found out that APIENTRY macro is required for each method in + abstract interface. + While I used different Microsoft C++ compilers - there were all ok. But + when I tried out MinGW and Borland C++ - method arguments were + corrupted. Adding macros solved this problem: +// The abstract interface for Xyz object. +// No extra specifiers required. +struct IXyz +{ + virtual int APIENTRY Foo(int n) = 0; // APIENTRY is required + virtual void APIENTRY Release() = 0; // APIENTRY is required +}; + + [265]Sign In·[266]View Thread·[267]PermaLink + General [268]Re: calling convention for each method in abstract class + is required [269]Pin member [270]Alex Blekhman 4:05 18 Feb '09 + I don't have Borland compiler handy to check this. However, if your + compiler supports __declspec(novtable) specifier, then you may apply it + to the IXyz interface: +struct __declspec(novtable) IXyz +{ + virtual int Foo(int n) = 0; + virtual void Release() = 0; +}; + + Pure virtual methods should not require any exporting as long as you + use only basic types (or interface pointers) as parameters. + [271]Sign In·[272]View Thread·[273]PermaLink + General [274]deriving the interface in EXE module [275]Pin member + [276]arif.setiawan 13:28 6 Feb '09 + Hi, + First, thank you for this great article. + I want to know your opinion about my case. + Suppose that I want to derive a child class from abstract interface in + EXE module and this child class can also use then implementation of the + interface in a class inside the dll which accessible through factory + function. An example would be : + I have a class: +class IAttribute +{ +public: + virtual int Save(const char *filename) = 0; + virtual int Load(const char *filename) = 0; +protected: + int left, right, top, bottom; +}; + + The actual implementation will be hidden in the dll by a class +class CAttribute : public IAttribute +{ + CAttribute(); + ~CAttribute(); + int Save(const char *filename); + int Load(const char *filename); +} + + which accessible by factory function GetAttribute() + Now I want to have a class in the MFC EXE which can draw the the + attributes, so I make a new class +class CEntity : public IAttribute +{ + CEntity (); + ~CEntity (); + void Draw(CDC* dc); + int Save(const char *filename); + int Load(const char *filename); +} + + Since the IAttribute provide no implementation of Save() and Load(), I + add a member pointer to the CAttribute so I can use functions defined + in the dll. +class CEntity : public IAttribute +{ +public: + CEntity (); + ... // same as above +private: + IAttribute *m_pAtttibute; +} + + Please tell me what your opinion about this, is this even possible? or + not correct from OOP perspective, really a bad design, or maybe there + is another approach that better than this. + I am doing this to make the dll MFC-independent and in some application + scenerio I just need to load the attribute only. + Thank you. + [277]Sign In·[278]View Thread·[279]PermaLink + General [280]Re: deriving the interface in EXE module [281]Pin member + [282]Alex Blekhman 1:27 7 Feb '09 + Hello, + First of all, you cannot have data members in IAttribute class. Having + data members in a class effectively makes it compiler dependent. If you + need data members, then provide getter/setter functions: +struct IAttribute +{ + ... + virtual int Left(void) const = 0; + virtual void Left(int l) = 0; +}; +class CAttribute : public IAttribute +{ +public: + // IAttribute implementation + ... + virtual int Left() const { return m_left; } + virtual void Left(int l) { m_left = l; } +private: + int m_left; +}; + + Now regarding CEntity class. There is no any problem in using data + member of type IAttribute that points to actual implementation in a + DLL. You have two options of reusing DLL's implementation: + 1. Containment/Delegation (forwarding calls): +class CEntity : public IAttribute +{ +public: + ... + int Save(const char *filename) + { + return m_pAttibute->Save(filename); + } + int Load(const char *filename) + { + return m_pAttibute->Load(filename); + } +}; + + 2. Aggregation: +class CEntity +{ +public: + ... + IAttribute *GetAttribute() const { return m_pAttibute; } +private: + IAttribute *m_pAttibute; +} + + Both methods are acceptable and quite common. Which of them is most + suitable for your project depends on your needs. + BTW, I'd suggest to use wide characters for filenames, so you will be + able to handle non-English filenames, as well. + [283]Sign In·[284]View Thread·[285]PermaLink + General [286]Re: deriving the interface in EXE module [287]Pin member + [288]arif.setiawan 19:35 8 Feb '09 + Thank you for your explanation. + Smile + [289]Sign In·[290]View Thread·[291]PermaLink + General [292]Abstract interface - question about disadvantages [293]Pin + member [294]mariusz102102 22:26 18 Nov '08 + You wrote: "An abstract interface method cannot return or accept a + regular C++ object as a parameter." + Could you explain me this limitation? What will (can) happen when I + pass regular C++ object to interface method? + Best regards, + Mariusz + [295]Sign In·[296]View Thread·[297]PermaLink + General [298]Re: Abstract interface - question about disadvantages + [299]Pin member [300]Alex Blekhman 23:49 18 Nov '08 + This problems stems from the binary incompatibility between C++ + compilers. When you pass a C++ object as a parameter, then teh compiler + should know how to call necessary copy constructors, destructors, etc; + what to do if any of this throws an exception; how to + allocate/deallocate memory, if the object (or one of its members) + requires that, etc. All this is compiler specific and cannot be shared + across different compilers. + If you want to accept C++ objects as a parameters (or return them from + methods) then you should treat such code as a static library, which can + be used with the same compiler only. + [301]Sign In·[302]View Thread·[303]PermaLink 5.00/5 (1 vote) + General [304]Importing to C# [305]Pin member [306]prodakn 11:27 10 Nov + '08 + That is a very good explanation for the "C++ Mature Approach". + Using this approach, would it be possible to access the C++ virtual + method from a C# wrapper? + [307]Sign In·[308]View Thread·[309]PermaLink + General [310]Re: Importing to C# [311]Pin member [312]Alex Blekhman + 12:20 10 Nov '08 + Hello, + Unfortunately C# cannot call C++ methods (be it global function, a + method of an abstract class or whatever). The C# programming language + has different object layout and method calling mechanics. That's what + Microsoft introduced C++/CLI - the C++ programming language that + supports both native and managed programming. C++/CLI is meant to be + the bridge between native world and .NET world. + If you need to use existing C++ code in .NET assembly, then C++/CLI is + the way to go. You can make a wrapper assembly with C++/CLI that calls + native C++ internally. Then such assembly could be used from other + managed languages. As an alternative, you can expose a C++ class with + plain C functions, which C# knows how to call via interop. + HTH + Alex + [313]Sign In·[314]View Thread·[315]PermaLink + General [316]Re: Importing to C# [317]Pin member [318]prodakn 17:14 10 + Nov '08 + Thanks for your quick reply. I will try the wrapper assembly with + C++/CLI. + Edit: + So I started looking into writing such a wrapper in C++/CLI. I'm + relatively unfamiliar with this language, but it looks like I can + #include the original C++ header file which uses the abstract + interface, and implement it as I would with C++; would this be the + route to go? + Appreciate your help, + Daniel + [319]Sign In·[320]View Thread·[321]PermaLink + General [322]Re: Importing to C# [323]Pin member [324]Alex Blekhman + 20:55 10 Nov '08 + Yes, C++/CLI is the full featured C++ plus additional extensions that + provide support for managed programming. The resulting code is compiled + into CLI, not to native binaries. If you want to connect between + existing C++ DLL and .NET assembly, then you can create a regular + managed class, which will call native C++ DLL. + In order to practice that, in Visual C++ go to new project wizard and + select there Visual C++ -> CLR -> CLR Console Application. Wizard will + generate an empty project very similar to C# console aplication. You + can include any C++ header in that project and use native DLL's without + any problem. + [325]Sign In·[326]View Thread·[327]PermaLink + General [328]unit testing [329]Pin member [330]rioch 23:03 23 Oct '08 + How would I go about unit testing classes in the dll that aren't + exported? + [331]Sign In·[332]View Thread·[333]PermaLink + General [334]Re: unit testing [335]Pin member [336]Alex Blekhman 22:13 + 2 Nov '08 + Hi. Sorry for delayed response, I've been on vacation last week. + Actually, there is nothing special about internal C++ classes that + reside within a DLL. You, as an author of the DLL have full control + over the source code. So, naturally, you develop test cases (using your + favourite testing framework) for internal classes in the same manner as + you do this for any other code you write. + Of course, TDD approach requires that you bear in mind the testing + process during design of software components, be it single C++ class or + full blown DLL module. There is no simple answer to your question. + Testing approach greatly depends on the nature of a class, its + interdependencies with other classes, etc. + Basically, I do similar unit tests for C++ classes within a DLL + regardless of whether they are exported or not. As a testing framework + I use CppUnit most of the time. Sometimes a project can require + slightly different testing framework, which is more tuned to the needs + of the project. Although it's a lot of a code to write for decent + testing coverage, but it pays off nicely during acceptance period + before releases. + [337]Sign In·[338]View Thread·[339]PermaLink + General [340]Re: unit testing [341]Pin member [342]rioch 3:02 5 Nov '08 + + No problem, thanks for replying, and I hope you enjoyed your holiday! + Smile + I think the problem lies in that the test framework runs in a separate + project, which includes the dll projects to be tested. Since my test + code is in a different project, only the exported classes are visible, + which leaves a lot of classes untestable. + [343]Sign In·[344]View Thread·[345]PermaLink + General [346]Re: unit testing [347]Pin member [348]Alex Blekhman 3:23 5 + Nov '08 + Engineering is all about tradeoffs. For each module/class one should + decide where to draw a line and what to test. Ideally, we should test + everything. It may involve some kind of a macro that will export every + class for test configuration builds. However, in practice testing every + single class/function can be prohibitively expensive. + Maybe in your case testing at the module level is good enough. After + all, as long as the module behaves as documented it is less important + (from the test point of view) how the module is implemented inside. In + my opinion, if you treat the module as a black box and make + comprehensive test harness that successfully covers all functionality + (including garbage input and extreme input), then you can assume quite + reliably that the module is tested well enough. + [349]Sign In·[350]View Thread·[351]PermaLink + General [352]Re: unit testing [353]Pin member [354]rioch 1:26 26 Feb + '09 + I'm not sure if I agree. Some of the code is gui based, but includes + complex elements such as zooming, which is in a non-exported class. + This zoom code is a prime candidate for unit testing, and doing this + via the dll interface is nigh on impossible. + I can think of two solutions: + 1) Write test classes in the dll and export them also. These classes + can be picked up by the test program. + 2) Export everything (I've never been a fan of exporting classes). + [355]Sign In·[356]View Thread·[357]PermaLink + General [358]Re: unit testing [359]Pin member [360]Alex Blekhman 2:49 + 26 Feb '09 + There is also third option: make special build for testing. In that + build one could export more than in regular release build etc. However, + as I wrote in the other post, it's a matter of tradeoff. + [361]Sign In·[362]View Thread·[363]PermaLink + General [364]Auto-releasing with boost::shared_ptr [365]Pin member + [366]Chris Marski 15:18 26 Sep '08 + I just wanted to point out that it is also possible to use + boost::shared_ptr for auto-releasing: +#include +#include +boost::shared_ptr foo (::GetFoo (), boost::mem_fn (&IFoo::Release)) + + (More interesting smart-pointer techniques here: + [367]http://www.boost.org/doc/libs/release/libs/smart_ptr/sp_techniques + .html[[368]^]) + It was a pleasure to read such a crystal-clear article. How about + expanding it and covering other platforms like Linux or Darwin. + [369]Sign In·[370]View Thread·[371]PermaLink + Question [372]DLLs and exception [373]Pin member [374]Member 3843328 + 12:42 22 Sep '08 + I wonder why DLLs and exception propagation do not mix. + Is it because including introduces a STL dependency? (I + checked STLport 5.1.4 - it seems to include the compilers' + only ...) + Or do different compilers really implement exception handling + differently? Could it be that even different compiler switches in the + DLL and the client cause trouble? + Roland + [375]Sign In·[376]View Thread·[377]PermaLink + Answer [378]Re: DLLs and exception [379]Pin member [380]Alex Blekhman + 12:53 22 Sep '08 + + Member 3843328 wrote: + + Or do different compilers really implement exception handling + differently? Could it be that even different compiler switches in + the DLL and the client cause trouble? + + Correct. This is exactly the reason. + [381]Sign In·[382]View Thread·[383]PermaLink + General [384]Inheritance [385]Pin member [386]NTRF 7:00 3 Sep '08 + Changing behaviour of base class in derived (using virtual functions) + is imposible using COM-like method because base classes can not + implement functions (in XPCOM this problem is solved using a huge and + ugly "defines"). The "Native C++" approach solves this problem, but + different DLLs created by different compilers might be incompatible. + The only posible approach is to use C-like functions with "handles". + This is exactly how IBM did class exports in their SOM (System Object + Model). + [387]Sign In·[388]View Thread·[389]PermaLink + Last Visit: 0:00 27 Sep '09 Last Update: 0:00 27 Sep '09 1[390]2 + [391]Next » + + General General News News Question Question Answer Answer + Joke Joke Rant Rant Admin Admin + [392]PermaLink | [393]Privacy | [394]Terms of Use + Last Updated: 31 Aug 2008 + Editor: [395]Smitha Vijayan + Copyright 2008 by Alex Blekhman + Everything else Copyright © [396]CodeProject, 1999-2009 + Web12 | [397]Advertise on the Code Project + +References + + 1. http://www.codeproject.com/webservices/articlerss.aspx?cat=1 + 2. http://www.codeproject.com/webservices/articlerss.aspx?cat=2 + 3. http://www.codeproject.com/webservices/articlerss.aspx?cat=3 + 4. http://www.codeproject.com/webservices/articlerss.aspx?cat=4 + 5. http://www.codeproject.com/webservices/articlerss.aspx?cat=5 + 6. http://www.codeproject.com/webservices/articlerss.aspx?cat=6 + 7. http://www.codeproject.com/webservices/LoungeRSS.aspx + 8. http://www.codeproject.com/info/OpenSearch.xml + 9. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#Main + 10. http://www.codeproject.com/script/Membership/SendPassword.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 11. http://www.codeproject.com/ + 12. http://www.codeproject.com/ + 13. http://www.codeproject.com/script/Articles/Latest.aspx + 14. http://www.codeproject.com/info/search.aspx + 15. http://www.codeproject.com/script/Articles/Latest.aspx + 16. http://www.codeproject.com/script/Articles/TopArticles.aspx?ta_so=4 + 17. http://www.codeproject.com/info/search.aspx?vidlst=152&sa_us=True + 18. http://www.codeproject.com/script/Articles/BlogArticleList.aspx + 19. http://www.codeproject.com/info/Submit.aspx + 20. http://www.codeproject.com/script/Articles/BlogFeed.aspx + 21. http://www.codeproject.com/info/Submit.aspx + 22. http://www.codeproject.com/script/Awards/CurrentCompetitions.aspx?cmpTpId=1 + 23. http://www.codeproject.com/script/Content/SiteMap.aspx + 24. http://www.codeproject.com/script/Forums/List.aspx + 25. http://www.codeproject.com/Forums/12076/ASP-NET.aspx + 26. http://www.codeproject.com/Forums/4486/ATL-WTL-STL.aspx + 27. http://www.codeproject.com/Forums/1647/C-Cplusplus-MFC.aspx + 28. http://www.codeproject.com/Forums/3785/Managed-Cplusplus-CLI.aspx + 29. http://www.codeproject.com/Forums/1649/Csharp.aspx + 30. http://www.codeproject.com/Forums/1648/COM.aspx + 31. http://www.codeproject.com/Forums/186301/Hardware-Devices.aspx + 32. http://www.codeproject.com/Forums/1004117/LINQ.aspx + 33. http://www.codeproject.com/Forums/1650/NET-Framework.aspx + 34. http://www.codeproject.com/Forums/1644/System-Admin.aspx + 35. http://www.codeproject.com/Forums/1004257/Silverlight.aspx + 36. http://www.codeproject.com/Forums/1725/General-Database.aspx + 37. http://www.codeproject.com/Forums/1540733/Sharepoint.aspx + 38. http://www.codeproject.com/Forums/1646/Visual-Basic.aspx + 39. http://www.codeproject.com/Forums/1640/Web-Development.aspx + 40. http://www.codeproject.com/Forums/1004114/WPF-WCF-WF.aspx + 41. http://www.codeproject.com/Forums/3421/XML-XSL.aspx + 42. http://www.codeproject.com/Forums/1642/General-IT-Issues.aspx + 43. http://www.codeproject.com/Forums/1645/Site-Bugs-Suggestions.aspx + 44. http://www.codeproject.com/Forums/1536756/The-Soapbox-2-0.aspx + 45. http://www.codeproject.com/script/Forums/List.aspx + 46. http://www.codeproject.com/script/Jobs/List.aspx + 47. http://www.codeproject.com/script/Jobs/List.aspx + 48. http://www.codeproject.com/script/Jobs/Search.aspx + 49. http://www.codeproject.com/script/Jobs/Edit.aspx + 50. http://www.codeproject.com/script/Jobs/FAQ.aspx + 51. http://www.codeproject.com/script/Catalog/List.aspx + 52. http://www.codeproject.com/script/Catalog/List.aspx?ctls=DatePostedDescending + 53. http://www.codeproject.com/script/Catalog/List.aspx + 54. http://www.codeproject.com/script/Catalog/Edit.aspx + 55. http://www.codeproject.com/script/Catalog/FAQ.aspx + 56. http://www.codeproject.com/info/FAQ.aspx + 57. http://www.codeproject.com/info/guide.aspx + 58. http://www.codeproject.com/info/FAQ.aspx + 59. http://www.codeproject.com/script/Forums/List.aspx + 60. http://www.codeproject.com/script/Content/SiteMap.aspx + 61. http://www.codeproject.com/info/about.aspx + 62. javascript:void(); + 63. javascript:void(); + 64. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=5 + 65. http://www.codeproject.com/KB/cpp/ + 66. http://www.codeproject.com/KB/cpp/index.aspx?#C / C++ Language - Howto + 67. http://www.codeproject.com/info/cpol10.aspx + 68. http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=224996 + 69. http://www.codeproject.com/Feature/ArticleCompetition/ + 70. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=1 + 71. http://www.codeproject.com/KB/buttons/ + 72. http://www.codeproject.com/KB/clipboard/ + 73. http://www.codeproject.com/KB/combobox/ + 74. http://www.codeproject.com/KB/dialog/ + 75. http://www.codeproject.com/KB/gadgets/ + 76. http://www.codeproject.com/KB/docview/ + 77. http://www.codeproject.com/KB/edit/ + 78. http://www.codeproject.com/KB/files/ + 79. http://www.codeproject.com/KB/grid/ + 80. http://www.codeproject.com/KB/list/ + 81. http://www.codeproject.com/KB/menus/ + 82. http://www.codeproject.com/KB/miscctrl/ + 83. http://www.codeproject.com/KB/printing/ + 84. http://www.codeproject.com/KB/progress/ + 85. http://www.codeproject.com/KB/selection/ + 86. http://www.codeproject.com/KB/shell/ + 87. http://www.codeproject.com/KB/smart/ + 88. http://www.codeproject.com/KB/splitter/ + 89. http://www.codeproject.com/KB/static/ + 90. http://www.codeproject.com/KB/statusbar/ + 91. http://www.codeproject.com/KB/tabs/ + 92. http://www.codeproject.com/KB/toolbars/ + 93. http://www.codeproject.com/KB/tree/ + 94. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=2 + 95. http://www.codeproject.com/KB/ajax/ + 96. http://www.codeproject.com/KB/applications/ + 97. http://www.codeproject.com/KB/asp/ + 98. http://www.codeproject.com/KB/aspnet/ + 99. http://www.codeproject.com/KB/webforms/ + 100. http://www.codeproject.com/KB/ATL-Server/ + 101. http://www.codeproject.com/KB/web-cache/ + 102. http://www.codeproject.com/KB/web-image/ + 103. http://www.codeproject.com/KB/scripting/ + 104. http://www.codeproject.com/KB/custom-controls/ + 105. http://www.codeproject.com/KB/HTML/ + 106. http://www.codeproject.com/KB/ISAPI/ + 107. http://www.codeproject.com/KB/server-management/ + 108. http://www.codeproject.com/KB/session/ + 109. http://www.codeproject.com/KB/silverlight/ + 110. http://www.codeproject.com/KB/trace/ + 111. http://www.codeproject.com/KB/user-controls/ + 112. http://www.codeproject.com/KB/validation/ + 113. http://www.codeproject.com/KB/viewstate/ + 114. http://www.codeproject.com/KB/WAP/ + 115. http://www.codeproject.com/KB/web-security/ + 116. http://www.codeproject.com/KB/webservices/ + 117. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=9 + 118. http://www.codeproject.com/KB/MCMS/ + 119. http://www.codeproject.com/KB/biztalk/ + 120. http://www.codeproject.com/KB/exchange/ + 121. http://www.codeproject.com/KB/office/ + 122. http://www.codeproject.com/KB/sharepoint/ + 123. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=3 + 124. http://www.codeproject.com/KB/audio-video/ + 125. http://www.codeproject.com/KB/directx/ + 126. http://www.codeproject.com/KB/GDI/ + 127. http://www.codeproject.com/KB/GDI-plus/ + 128. http://www.codeproject.com/KB/graphics/ + 129. http://www.codeproject.com/KB/openGL/ + 130. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=4 + 131. http://www.codeproject.com/KB/database/ + 132. http://www.codeproject.com/KB/reporting-services/ + 133. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=8 + 134. http://www.codeproject.com/KB/atl/ + 135. http://www.codeproject.com/KB/MFC/ + 136. http://www.codeproject.com/KB/stl/ + 137. http://www.codeproject.com/KB/wtl/ + 138. http://www.codeproject.com/KB/COM/ + 139. http://www.codeproject.com/KB/dotnet/ + 140. http://www.codeproject.com/KB/winsdk/ + 141. http://www.codeproject.com/KB/vista/ + 142. http://www.codeproject.com/KB/vista-security/ + 143. http://www.codeproject.com/KB/cross-platform/ + 144. http://www.codeproject.com/KB/game/ + 145. http://www.codeproject.com/KB/mobile/ + 146. http://www.codeproject.com/KB/WC/ + 147. http://www.codeproject.com/KB/WCF/ + 148. http://www.codeproject.com/KB/WPF/ + 149. http://www.codeproject.com/KB/WF/ + 150. http://www.codeproject.com/KB/library/ + 151. http://www.codeproject.com/KB/powershell/ + 152. http://www.codeproject.com/KB/linq/ + 153. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=5 + 154. http://www.codeproject.com/KB/cpp/ + 155. http://www.codeproject.com/KB/mcpp/ + 156. http://www.codeproject.com/KB/cs/ + 157. http://www.codeproject.com/KB/msil/ + 158. http://www.codeproject.com/KB/vbscript/ + 159. http://www.codeproject.com/KB/vb/ + 160. http://www.codeproject.com/KB/vb-interop/ + 161. http://www.codeproject.com/KB/net-languages/ + 162. http://www.codeproject.com/KB/XML/ + 163. http://www.codeproject.com/KB/java/ + 164. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=6 + 165. http://www.codeproject.com/KB/recipes/ + 166. http://www.codeproject.com/KB/bugs/ + 167. http://www.codeproject.com/KB/collections/ + 168. http://www.codeproject.com/KB/security/ + 169. http://www.codeproject.com/KB/datetime/ + 170. http://www.codeproject.com/KB/DLL/ + 171. http://www.codeproject.com/KB/exception/ + 172. http://www.codeproject.com/KB/locale/ + 173. http://www.codeproject.com/KB/macros/ + 174. http://www.codeproject.com/KB/tips/ + 175. http://www.codeproject.com/KB/string/ + 176. http://www.codeproject.com/KB/IP/ + 177. http://www.codeproject.com/KB/threads/ + 178. http://www.codeproject.com/KB/winhelp/ + 179. http://www.codeproject.com/KB/FAQ/ + 180. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=10 + 181. http://www.codeproject.com/KB/expression/ + 182. http://www.codeproject.com/KB/usability/ + 183. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=11 + 184. http://www.codeproject.com/KB/debug/ + 185. http://www.codeproject.com/KB/architecture/ + 186. http://www.codeproject.com/KB/install/ + 187. http://www.codeproject.com/KB/work/ + 188. http://www.codeproject.com/KB/testing/ + 189. http://www.codeproject.com/KB/codegen/ + 190. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=7 + 191. http://www.codeproject.com/KB/books/ + 192. http://www.codeproject.com/KB/book-reviews/ + 193. http://www.codeproject.com/KB/hardware-review/ + 194. http://www.codeproject.com/KB/interviews/ + 195. http://www.codeproject.com/KB/scrapbook/ + 196. http://www.codeproject.com/KB/system/ + 197. http://www.codeproject.com/KB/Blogs/ + 198. http://www.codeproject.com/KB/mentor/ + 199. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=12 + 200. http://www.codeproject.com/KB/showcase/ + 201. http://www.codeproject.com/KB/solution-center/ + 202. http://www.codeproject.com/script/Content/Chapter.aspx?chptId=13 + 203. http://www.codeproject.com/script/Catalog/List.aspx + 204. http://www.codeproject.com/services/certificates/index.aspx + 205. http://www.codeproject.com/script/Jobs/List.aspx + 206. http://www.codeproject.com/Services/Addins/ + 207. http://www.codeproject.com/kb/Showcase/ + 208. http://www.codeproject.com/info/search.aspx + 209. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?display=Print + 210. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 211. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#_comments + 212. http://www.codeproject.com/script/Articles/Report.aspx?aid=28969 + 213. http://www.codeproject.com/script/Articles/TopArticles.aspx?ta_so=1 + 214. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes/XyzSample_src.zip + 215. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#Introduction + 216. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#CLanguageApproach + 217. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#CppNaiveApproach + 218. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#CppMatureApproach + 219. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#WhatAboutSTL + 220. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#Summary + 221. http://www.dependencywalker.com/ + 222. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes/Xyz.png + 223. http://en.wikipedia.org/wiki/RAII + 224. http://www.codeproject.com/info/cpol10.aspx + 225. http://www.codeproject.com/Members/Alex-Blekhman + 226. http://www.codeproject.com/KB/cpp/FastDelegate.aspx + 227. http://www.codeproject.com/KB/cpp/exceptionhandler.aspx + 228. http://www.codeproject.com/KB/cpp/pointers.aspx + 229. http://www.codeproject.com/KB/cpp/markupclass.aspx + 230. http://www.codeproject.com/KB/cpp/pugxml.aspx + 231. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#_top + 232. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx#SignUp + 233. http://www.codeproject.com/script/Adm/ServeLinks.aspx?C=False&ids=10693,5226,8560 + 234. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx%3ffid%3d1525934%26df%3d90%26mpp%3d25%26noise%3d3%26sort%3dPosition%26view%3dQuick + 235. http://www.codeproject.com/script/Forums/FAQ.aspx + 236. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&noise=3&sort=Position&view=Quick + 237. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx + 238. http://www.codeproject.com/Messages/3047719/source-file-path-in-cplusplus.aspx + 239. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 240. http://www.codeproject.com/script/Membership/View.aspx?mid=112271 + 241. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 242. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=3047719 + 243. http://www.codeproject.com/Messages/3047719/source-file-path-in-cplusplus.aspx + 244. http://www.codeproject.com/Messages/3047926/Re-source-file-path-in-cplusplus.aspx + 245. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 246. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 247. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 248. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=3047719 + 249. http://www.codeproject.com/Messages/3047926/Re-source-file-path-in-cplusplus.aspx + 250. http://www.codeproject.com/Messages/2974529/Static-library.aspx + 251. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 252. http://www.codeproject.com/script/Membership/View.aspx?mid=67130 + 253. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 254. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2974529 + 255. http://www.codeproject.com/Messages/2974529/Static-library.aspx + 256. http://www.codeproject.com/Messages/2974746/Re-Static-library.aspx + 257. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 258. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 259. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 260. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2974529 + 261. http://www.codeproject.com/Messages/2974746/Re-Static-library.aspx + 262. http://www.codeproject.com/Messages/2929651/calling-convention-for-each-method-in-abstract-cla.aspx + 263. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 264. http://www.codeproject.com/script/Membership/View.aspx?mid=3796799 + 265. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 266. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2929651 + 267. http://www.codeproject.com/Messages/2929651/calling-convention-for-each-method-in-abstract-cla.aspx + 268. http://www.codeproject.com/Messages/2929769/Re-calling-convention-for-each-method-in-abstract-.aspx + 269. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 270. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 271. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 272. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2929651 + 273. http://www.codeproject.com/Messages/2929769/Re-calling-convention-for-each-method-in-abstract-.aspx + 274. http://www.codeproject.com/Messages/2914580/deriving-the-interface-in-EXE-module.aspx + 275. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 276. http://www.codeproject.com/script/Membership/View.aspx?mid=481877 + 277. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 278. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2914580 + 279. http://www.codeproject.com/Messages/2914580/deriving-the-interface-in-EXE-module.aspx + 280. http://www.codeproject.com/Messages/2914888/Re-deriving-the-interface-in-EXE-module.aspx + 281. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 282. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 283. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 284. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2914580 + 285. http://www.codeproject.com/Messages/2914888/Re-deriving-the-interface-in-EXE-module.aspx + 286. http://www.codeproject.com/Messages/2916069/Re-deriving-the-interface-in-EXE-module.aspx + 287. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 288. http://www.codeproject.com/script/Membership/View.aspx?mid=481877 + 289. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 290. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2914580 + 291. http://www.codeproject.com/Messages/2916069/Re-deriving-the-interface-in-EXE-module.aspx + 292. http://www.codeproject.com/Messages/2811832/Abstract-interface-question-about-disadvantages.aspx + 293. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 294. http://www.codeproject.com/script/Membership/View.aspx?mid=1524771 + 295. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 296. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2811832 + 297. http://www.codeproject.com/Messages/2811832/Abstract-interface-question-about-disadvantages.aspx + 298. http://www.codeproject.com/Messages/2811922/Re-Abstract-interface-question-about-disadvantages.aspx + 299. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 300. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 301. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 302. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2811832 + 303. http://www.codeproject.com/Messages/2811922/Re-Abstract-interface-question-about-disadvantages.aspx + 304. http://www.codeproject.com/Messages/2800995/Importing-to-Csharp.aspx + 305. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 306. http://www.codeproject.com/script/Membership/View.aspx?mid=5681852 + 307. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 308. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2800995 + 309. http://www.codeproject.com/Messages/2800995/Importing-to-Csharp.aspx + 310. http://www.codeproject.com/Messages/2801060/Re-Importing-to-Csharp.aspx + 311. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 312. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 313. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 314. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2800995 + 315. http://www.codeproject.com/Messages/2801060/Re-Importing-to-Csharp.aspx + 316. http://www.codeproject.com/Messages/2801252/Re-Importing-to-Csharp.aspx + 317. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 318. http://www.codeproject.com/script/Membership/View.aspx?mid=5681852 + 319. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 320. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2800995 + 321. http://www.codeproject.com/Messages/2801252/Re-Importing-to-Csharp.aspx + 322. http://www.codeproject.com/Messages/2801428/Re-Importing-to-Csharp.aspx + 323. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 324. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 325. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 326. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2800995 + 327. http://www.codeproject.com/Messages/2801428/Re-Importing-to-Csharp.aspx + 328. http://www.codeproject.com/Messages/2778527/unit-testing.aspx + 329. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 330. http://www.codeproject.com/script/Membership/View.aspx?mid=4264334 + 331. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 332. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 333. http://www.codeproject.com/Messages/2778527/unit-testing.aspx + 334. http://www.codeproject.com/Messages/2790557/Re-unit-testing.aspx + 335. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 336. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 337. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 338. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 339. http://www.codeproject.com/Messages/2790557/Re-unit-testing.aspx + 340. http://www.codeproject.com/Messages/2794531/Re-unit-testing.aspx + 341. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 342. http://www.codeproject.com/script/Membership/View.aspx?mid=4264334 + 343. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 344. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 345. http://www.codeproject.com/Messages/2794531/Re-unit-testing.aspx + 346. http://www.codeproject.com/Messages/2794568/Re-unit-testing.aspx + 347. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 348. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 349. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 350. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 351. http://www.codeproject.com/Messages/2794568/Re-unit-testing.aspx + 352. http://www.codeproject.com/Messages/2940572/Re-unit-testing.aspx + 353. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 354. http://www.codeproject.com/script/Membership/View.aspx?mid=4264334 + 355. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 356. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 357. http://www.codeproject.com/Messages/2940572/Re-unit-testing.aspx + 358. http://www.codeproject.com/Messages/2940688/Re-unit-testing.aspx + 359. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 360. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 361. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 362. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2778527 + 363. http://www.codeproject.com/Messages/2940688/Re-unit-testing.aspx + 364. http://www.codeproject.com/Messages/2741752/Auto-releasing-with-boost-shared_ptr.aspx + 365. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 366. http://www.codeproject.com/script/Membership/View.aspx?mid=811855 + 367. http://www.boost.org/doc/libs/release/libs/smart_ptr/sp_techniques.html + 368. http://www.boost.org/doc/libs/release/libs/smart_ptr/sp_techniques.html + 369. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 370. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2741752 + 371. http://www.codeproject.com/Messages/2741752/Auto-releasing-with-boost-shared_ptr.aspx + 372. http://www.codeproject.com/Messages/2734948/DLLs-and-exception.aspx + 373. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 374. http://www.codeproject.com/script/Membership/View.aspx?mid=3843328 + 375. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 376. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2734948 + 377. http://www.codeproject.com/Messages/2734948/DLLs-and-exception.aspx + 378. http://www.codeproject.com/Messages/2734964/Re-DLLs-and-exception.aspx + 379. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 380. http://www.codeproject.com/script/Membership/View.aspx?mid=224996 + 381. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 382. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2734948 + 383. http://www.codeproject.com/Messages/2734964/Re-DLLs-and-exception.aspx + 384. http://www.codeproject.com/Messages/2706638/Inheritance.aspx + 385. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx + 386. http://www.codeproject.com/script/Membership/View.aspx?mid=3932000 + 387. http://www.codeproject.com/script/Membership/LogOn.aspx?rp=%2fKB%2fcpp%2fhowto_export_cpp_classes.aspx + 388. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&sort=Position&tid=2706638 + 389. http://www.codeproject.com/Messages/2706638/Inheritance.aspx + 390. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx + 391. http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx?fid=1525934&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx + 392. http://www.codeproject.com/script/Articles/Article.aspx?aid=28969 + 393. http://www.codeproject.com/info/privacy.aspx + 394. http://www.codeproject.com/info/TermsOfUse.aspx + 395. http://www.codeproject.com/script/Membership/View.aspx?mid=28970 + 396. mailto:webmaster@codeproject.com + 397. http://www.codeproject.com/info/MediaKit.aspx -- cgit v1.2.3-54-g00ecf