#### Archived

This topic is now archived and is closed to further replies.

This topic is 5936 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

##### Share on other sites
Hi,
I believe you can compile a dll without an entry point (unless it is an MFC Dll which need the Dll main entry point). you must be aware that if you use any class/function that appear in the dll, directly, the project will link to the dll.

##### Share on other sites
Hi,

What you want to do is loading the DLL dynamically, if I got that right, which means that you do not want to use a .lib-file. Well, it isn''t that hard:

The DLL has to _export_ functions if you want to use them in another program. (This is only partially correct, see later). To export a function, do the following:

  extern "C" __declspec(dllexport) void* __cdecl AnyFunction(void);

Let''s go through this code step by step.
extern "C" tells the compiler not to use name mangling, a technique used by C++ to be able to resolve the correct function when overloading is used.

__declspec(dllexport) is MS-Specific, but DLLs are too. It tells the compiler to export the function.

void* is just an example return type, but note that it has to appear in front of the calling convention.

__cdecl tells the compiler to use the standard C-Calling convention. A calling convetion determines whether the caller or the called has to clear up the stack, and so forth, take it as is.

That function is then exported. To get it in your main Program, just do the following:

  HMODULE hModule = LoadLibrary("mydll.dll");void*(*PFNANYFUNCTION)(void) = 0;PFNANYFUNCTION = GetProcAddress(hModule, "AnyFunction");

As it is somewhat annoying to type that stuff for every function you export, you can create an instance of class in your DLL, that is derived from a pure-virtual class (a class that contains pure virtual functions only). The main program does only have knowledge about that pure virtual class, so that it is not neccessary to have *anything* needed in the DLL given to the main program, things such as 3rd party libraries.

quote:

be aware that if you use any class/function that appear in the dll, directly, the project will link to the dll.

Well, depends on compiler I guess, but MSVC++ does not do this, if there is no dependency between the two projects. It just gives you an error, because the function is unknown. You may, of course, not use .lib-files or have the depencies set, because the dependencies use the lib file if neccessary.

Hope that helps.

##### Share on other sites
Well, you have to export the functions regardless when compiling the DLL even if you plan on using the import library, don''t you? All of my container classes are compiled with the __declspec(dllexport) storage class identifier, and included in my applications with a different header file which replaces it with __declspec(dllimport) so that it will automatically import the functions in the import library. My question was more one of usage than definition. See, how I understand it, if you compile your application with the import library, the application code automatically loads the library dynamically on application startup and releases it when the application closes. This is fine, but I want more control over when the library is loaded and released. This way, I only load code for the file-loader classes when they need to be used (at initialization time to attach the resources to my progam and when the resources need to be restored due to surfaces/buffers lost) and free them when I''m done using them, as opposed to loading the code at the beginning of the program and releasing it at the end.

I know I don''t need to provide a dll entry point if I use the import library, but do I need to provide a dll entry point in the DLL if I use LoadLibrary() to load the DLL instead?

##### Share on other sites
Actually, I have a slightly different question now. Let''s say I use LoadLibrary() to load the DLL that contains my file loader container classes and I want to create an empty instance of DDBITMAP and load in a .ddb file with its corresponding Load() function. Do I need to use GetProcAddress() to retrieve the addresses of the class member functions, and if so, how would I do this? The MSVC++ documentation is surprisingly sparse on this topic.

##### Share on other sites
You would have to take the name mangling into account when loading the class methods from the dll, and manually reconstruct the v-tables to instance the class, to do it that way.

You want to do what PS2000 suggested, and make a dll export that instances a class and returns a pointer to it. Then you just need one common header with the class declaration in it to share between the program and the dll.

This is one of the things COM does, if you want to look into that after you understand how dynamic dll loading works. Crude&Rude ATL Tutorial found here

##### Share on other sites
Oh, wait a minute. I think I get it. You mean, I should create a function in the DLL that returns a pointer to a file-loader, so I don''t have to manually recreate the v-table for the file-loader class. Maybe something along these lines?

  CFile* __declspec(dllexport) GetFileObject(unsigned long class_id){ switch(class_id) { case BMP: CBmp * bitmap = new CBmp; return bitmap; case DDB: CDdb * ddbitmap = new CDdb; return ddbitmap; case WAV: CWav * wave = new CWav; return wave; default: break; } return NULL;}

I would still need to get the proc address of this function regardless, after loading the library. If I extern "C" {} the function, the compiler won''t mangle the name, so would this code work then:

  typedef CFile* (__cdecl* LPFACTORYFUNC)(unsigned long);HINSTANCE hdllmodule = LoadLibrary("fileload.dll");LPFACTORYFUNC lpfnFactory = GetProcAddress(hdllmodule, "GetFileObject");if(!lpfnFactory) exit(1);CBmp * bitmapfile = lpfnFactory(BMP);bitmapfile.Load("foo.bmp");// rectify bitmap image to surfacedelete bitmapfile;FreeLibrary(hdllmodule);

##### Share on other sites
Yep, similar to what we do with some of our stuff.

extern "C" gets a bit messy, much easier is to use a .DEF file:

  LIBRARY MyDLLsNameEXPORTS GetFileObject @1 AnotherFunction @2 AndYetAnotherOne @3SECTIONS .data READ WRITE

Call that file the same name as your DLL, but with a .DEF extension, then Add it to your ptoject. Voila - no mangled names for the exported functions in your def.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

##### Share on other sites
Hey, thanks guys That really helps my understanding.