Click here to Skip to main content
Click here to Skip to main content

Exporting C++ classes without using MFC extension DLL

By , 5 Jun 2002
 

Introduction

DLLs are a great way of sharing common pieces of code data between applications. When it comes down to exporting C++ classes from DLLs most of us go for MFC extension DLLs where we can use the AFX_EXT_CLASS macro to export an entire class. Unfortunately, MFC is no lean and mean class architecture, which means that distributing MFC extension DLLs mean that you have to include the big MFC runtime not to mention the fact that your DLL can only be linked to MFC applications exclusively. What's the solution then? Enter standard Win32 DLLs.

Details

I couldn't believe my eyes on how easily one can export C++ classes directly from a plain vanilla Win32 DLL. Just make one and insert your classes into the DLL. Now simply put __declspec(dllexport) in between the class keyword and the class name, i.e.

// in your header...

class __declspec(dllexport) CDllTest
{
public:  
  CDllTest(){}
  ~CDllTest(){}

public:
  void SayHello();
};

// in your cpp...

void CDllTest::SayHello()
{
 printf(_T("Hello C++"));
}

That's it! The sample code and project are pretty self explanatory. Enjoy.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Tanzim Husain
Web Developer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionI got lilnker error LN2019memberVivek_Mendse10 Nov '11 - 18:52 
error LNK2019: unresolved external symbol "public: void __thiscall Test::funa(void)" (?funa@Test@@QAEXXZ) referenced in function _main
1>C:\VISUAL_STUDIO_2010\test_exe\Debug\test_exe.exe : fatal error LNK1120: 1 unresolved externals
 

code :
Dll header Export_Class.h
 
class __declspec(dllexport) Test
{
 
public:
    Test(){}
    ~Test(){}
    void funa(void);
};
 
dll cpp
 

void Test::funa()
{
    cout<<"hello world \n";
}
 

cpp of exe
 
#include<iostream>
#include"Export_Class.h"
using namespace std;
 
int main()
{
    Test t;
    t.funa();
    return 0;
}

QuestionReally - that simple?memberVaclav_Sal4 Feb '11 - 8:48 
You are using incorrect assumptions (per MSDN) when the DLL is used in conjunction with MFC application.
I say assumptions because you did not define that, therefore, your article is little misleading.
Per MSDN the macro usage depends on definition or no definitions of _AFXDLL and _AFXEXT.
I just followed you advice and replaced the macro AFX_EXT_CLASS with __declspec(dllexport) only to get the compiler   not to recognize MFC CWnd base class(!) I have only _AFXDLL defined, so it makes perfect sense.
GeneralUsing dllmembers_t_r_e_a_m_e_r18 Nov '07 - 1:19 
Actually it is very simple to include this dll into your project. After compiling the dll, Visual Studio creates one lib file beside dll file. Include just header of dll class you want to use into your project, and link it with .lib file. And there is no need for load library Smile | :) .
QuestionHow can I use a class exported from a DLL by using LoadLibrary functionmemberzhoujinjun085827 Aug '07 - 4:22 
I want to use exported C++ classes from a Dll.You know,by using the three functions LoadLibrary ,GetProcAddress,FreeLibrary ,we can use a Dll explicitly .But GetProcAddress function is only used for getting the address of the specified exported DLL function.
Can I use exported-classes by using those functions.
My English is very poor,so I don't know whether you can understand what i mean!
Anywhere ,I will thank you for giving us a so great experience!
 
I hope to have a nice trip!

AnswerRe: How can I use a class exported from a DLL by using LoadLibrary functionmemberafriza2 Dec '08 - 16:44 
If you want to use the class while loading the library *explicitly*, you can write a function that create the class instance and return it.
e.g.
 
extern "C" __declspec(dllexport) MyClassInDLL* CreateMyClassInDLL() {
   return new MyClassInDLL;
}

GeneralGreat!memberdocrob125 Jan '07 - 17:48 
Wink | ;) I suppose I'm too much of a beginner, but I really gained a lot from your article. Thanks for presenting a simple solution to a common problem.
 
docrob1
Generaldelete cuases access violationmembertom cruz18 Aug '05 - 2:35 
I hav e done the same thing in borland builder but
I get an access violation when I use delete.
if I declare the object as so in a function
 
cwidget cw;
 
and just let it fall throught the function. it destroys
itself with no error. why does not delete work to destroy
the object.

 
tom cruz
GeneralRe: delete cuases access violationmemberIgen19 Mar '09 - 7:14 
tom cruz wrote:
and just let it fall throught the function. it destroys
itself with no error.

 
Is it means to let the garbage collector handle the leak?
 
Anyway the standard solution which I red everywhere is to make a Release() function that has delete *this; if I remember right. And all you have to do is to call xxx->Release();. DirectX classes is works the same as far as I know.
GeneralqnsussFrom_Nepal6 Jan '05 - 8:00 
after exporting classes how do I access it's member function from another module by using run time dynamic linking (LoadLibrary, GetProcAddress...)?
GeneralLoad at runtimememberVerifier16 Apr '04 - 4:30 
How can I load a DLL with classes at runtime?
GeneralRe: Load at runtimememberThatsAlok20 Apr '06 - 22:32 
Verifier wrote:
How can I load a DLL with classes at runtime?

 
No U cannot, actually Class function get it address only when there Object is created!.
 

"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow

cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
QuestionHow to create DllTest.dll and DllTest.lib in VC7.0memberSctt H. Chang31 Mar '04 - 10:11 
Hi all,
I am a new DLL user of VC7.0 (VC++ .NET 2002)on Windows XP Pro PC and I do not know how to use the .cpp and .h files of Husain's DllTest and DllTestApp to create DllTest.dll and DllTest.lib. Please help and give me some detailed instructions for creating the DllTest.dll and DllTest.lib on the Win32 project of VC++ .NET 2002.
Thanks in advance,
Scott Chang

AnswerRe: How to create DllTest.dll and DllTest.lib in VC7.0sussAnonymous17 Apr '04 - 23:26 
Err... VC7.0 can import/open VC6.0 projects out of the box, so you should not have any problem opening the existing example.
 
Regards,
TH
Questionis it mean that regular DLL can replace extension DLL every time?memberdalink6 Mar '04 - 6:00 
is it mean that regular DLL can replace extension DLL every time?
 
dd
GeneralA slight correction and enhancementmemberDavid Pritchard29 May '03 - 7:31 
I don't think this has been made clear: for the exporting DLL, the class name must be prefixed by
 
__declspec(dllexport)
 
and for the importing DLL / EXE, prefixed by
 
__declspec(dllimport)
 
hence the AFX_EXT_CLASS macro, which is defined as one or the other accordingly. If you don't do this, the export won't work properly.
 
So, how do you make this work? Simple, define a symbol in your DLL (say _MYDLL), derived from the name, that will only be defined in the DLL. Then define another symbol (say EXPORT_FROM_MYDLL) which is defined as __declspec(dllexport) when _MYDLL is defined, and __declspec(dllimport) when it's not. Put the second symbol before the class name in the header that you export to clients.
 
Here's the scheme, wrapped up in a header (MyDLLExport.h) which you should #include in all headers which clients see (all exported class headers). It also auto-includes the lib for clients, which is another very handy idea I came across recently.
 
#ifndef MYDLLEXPORT_H
#define MYDLLEXPORT_H
 
// Define the import/export directive
// Define the lib include directive for clients only
#ifdef _MYDLL
	#define EXPORT_FROM_MYDLL __declspec(dllexport)
#else
	#define EXPORT_FROM_MYDLL __declspec(dllimport)
<p>
	// Clients will link with library automatically providing they have specified the lib 
	// directory in their "additional library path" option or elsewhere
	#ifndef _UNICODE
		#ifdef _DEBUG
			#pragma comment (lib, "MyDlld.lib")				// Include ANSI debug MyDll lib
		#else
			#pragma comment (lib, "MyDll.lib")				// Include ANSI release MyDll lib
		#endif
	#else
		#ifdef _DEBUG
			#pragma comment (lib, "MyDllud.lib")				// Include Unicode debug MyDll lib
		#else
			#pragma comment (lib, "MyDllu.lib")				// Include Unicode release MyDll lib
		#endif
	#endif
#endif
 

#endif

 
The whole business of not being able to export classes from regular DLLs is a huge myth. I've been doing it for years without a problem. I do sometimes get a couple of warnings about classes "not having a DLL interface" though, which I disable with a pragma:
 
#pragma warning( disable : 4251 4275 )  
I don't know if some terrible doom awaits me for doing this, but nothing's happened so far.Cool | :cool:
Questionhow to insert a class from MFC to C#membermosgeorge13 Apr '03 - 3:49 
I created a MFC class like you described and tried to insert it to C# project, but I didn't know how to insert it in c# project.
If you can, please give some examples that describe it.
AnswerRe: how to insert a class from MFC to C#memberTanzim Husain23 Apr '03 - 20:54 
Er... I'm afraid I have no clue on C#... haven't even played with VC.Net yet...just installed it and left it to rot Wink | ;)
 
Tanzim Husain
AnswerRe: how to insert a class from MFC to C#memberTakeru Koushirou27 Jun '04 - 21:31 
It's not possible to import a general C++ class to C#, and, correct me if I'm wrong, this include MFC classes, too.
In C# you can only import standard C functions using the DllImport attribute before declarating an extern function.
 
--------------------------
xplo.re Project Management
http://xplo-re.com/
http://koushiro.de/
GeneralRe: how to insert a class from MFC to C#membercharnos13 Aug '04 - 6:49 
It is, however, possible to refactor your C++ dll with Managed Extensions, either by making it directly useable by .NET classes, or by creating .NET-friendly wrapper classes that manipulate the existing C++ objects in the appropriate way. When someone mentions C# though, I get the idea that they're trying to get Windows.Forms and MFC to play together, and the implications of that make the hairs on the back of my neck stand up.
Generalany Info about Proxy DLL (Trojan DLL)memberbfadi5 Mar '03 - 10:24 
I know that I should use #pragma comment(linker, "/export:DoSomething=DllImpl.ActuallyDoSomething")
But I have not any explication for it
Thanks

Cool | :cool:
GeneralRe: any Info about Proxy DLL (Trojan DLL)memberTanzim Husain23 Apr '03 - 21:14 
U should go for dll code injection for stuff like that Wink | ;)
Jeffery Richter's Advanced Windows Programming has some nice information on it.
 
Tanzim Husain
GeneralRe: any Info about Proxy DLL (Trojan DLL)membergypsySUN17 Oct '03 - 18:11 
on 5 Mar '03 bfadi wrote:
I know that I should use #pragma comment(linker, "/export:DoSomething=DllImpl.ActuallyDoSomething")
But I have not any explication for it

 

This is a little late perhaps,
but
try here for #pragma comment[^]
see here for linker options[^]
 
Incase the links don't work. I cut the relevant bits from MSDN:
 
#pragma comment( comment-type [, commentstring] )
Places a linker option in the object file. You can use this comment-type to specify a linker option instead of placing the option on the Link tab of the Project Settings dialog box. For example, you can specify the /include option to force the inclusion of a symbol:
 
#pragma comment(linker, "/include:__mySymbol")
 

 
Syntax
/EXPORT:entryname[=internalname]
With this option, you can export a function from your program so that other programs can call the function. You can also export data. Exports are usually defined in a DLL.
 
The entryname is the name of the function or data item as it is to be used by the calling program. You can optionally specify the internalname as the function known in the defining program; by default, internalname is the same as entryname.
 

So you can see that by redefining the internalname to be a call to a function exported by another dll, you can have your wrapper dll export the interface of the other dll(or part of it).
GeneralRe: any Info about Proxy DLL (Trojan DLL)memberbfadi18 Oct '03 - 20:42 
Thanks very much for the answer , its NOT too late. Its just on timeSmile | :)
 
I have more questions if you have time to help me please.
How can I know the argument of a function exported from a DLL ???????
Like the functions exported from NTDLL.DLL like NTDeleteFile
This function not fount in the DDK ?
Thanks very very much
Rose | [Rose] Rose | [Rose] Rose | [Rose]
 

GeneralRe: any Info about Proxy DLL (Trojan DLL)membergypsySUN21 Oct '03 - 5:27 
I'm afraid that's a bit beyond me to answer.
 
I can tell you there is no easy was to find out if a function signature
is not documented, what the return type and args are. I think it is usually done by stepping through an assembly at the point of the call and making an educated guess, then testing it.
 
With regard to NTDLL.DLL if you were just interested in the undocumented
API for this dll in particular you are in luck as it has mostly been revealed at
ntinternals.net[^]
 
For native API you could start at sysinternals.com[^]
 
For more dynamic API interception the
Detours[^]
library looks very useful, but one has to know the function signatures.

sorry I can't help any more than this. Frown | :(
GeneralRe: any Info about Proxy DLL (Trojan DLL)memberbfadi21 Oct '03 - 19:57 
Thanks very much
Fadi
 
Rose | [Rose]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 6 Jun 2002
Article Copyright 2002 by Tanzim Husain
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid