Exporting classes from a DLL?

Started by
7 comments, last by Ivyn 21 years, 1 month ago
I'm working on a game engine and I want it to be a DLL (Dynamic Link Library) so I can access it from multiple programming languages and it will be easy to update...etc. Basically it will take care of all the graphics, sound, input, and I want it to have special functions to make it easy to create tile-based games and use other 2D effects. I read somewhere that DLLs cannot export classes or objects unless you use COM or another advanced method. Is this true? If so I was wondering if it was worth it or should I just go ahead and make a non-object-oriented engine? Which method is most common and better to create and access, OO or non-OO? I hope I'm clear enough, thanks for your help! [edited by - Ivyn on March 6, 2003 8:03:29 PM]
-- Ivyn --
Advertisement
Depending on how you want to do it you can export whole classes or just parts of them (actually, you would be exporting an object...). You do not need COM to achieve this. COM just adds a layer of abstraction between you and the dll - think of it as a programming pattern that is a superset of shared objects (dlls).

Check out the msdn online library and lookup dlls. Theres some pretty good introductory material in there that should start your gears spinning and some example code to get you started.

I personally set up my engine this way, where the rendering engine can use either GL or DirectX - it just depends on what dll it loads at runtime. Everything is abstracted: video, sound, music, vm, etc... The nice thing is once the core engine was finished it acts like a test harness as you build other pieces of your code. It also allows me to support other systems by just building a dll that exports the required interface - sort of like COM, just *very* simplified. So sound can just do DirectX, or Miles, etc by building a new dll.


Good luck and enjoy.



"C and C++ programmers seem to think that the shortest distance between two points is the great circle route on a spherical distortion of Euclidean space."Stephen Dewhurst
Thank you very much for taking the time to help. I'm afraid I'm still quite lost however. You are saying it is possible to export classes then, right? I'm not sure how I should go about doing this tho.

Perhaps I should elaborate on what I want the end result of the engine to be. What I want to do is create a system which would work like...

[PSEUDO CODE]
The user creates a new sprite called MySprite and is able to edit such properties as:
MySprite.Width = 102;
MySprite.Height = 98;
MySprite.Visible = True;

I'm newbieish to the whole using DLLs for this purpose so I don't know if this is possible or not with using COM.
Thanks all!

[edited by - Ivyn on March 6, 2003 8:11:11 PM]
-- Ivyn --
I was working in something like this last year and I ran into some major problems that took me months to fix.

The problem was the reservation and freeing of memory. Apparently a DLL has it''s own heap. Any functions / methods in the DLL reserve memory on the heap of the DLL, not your executable. So never EVER free memory from your main program that a function inside the DLL reserved.

I worked around it by defining a set of my own memory reservation functions which simply call malloc() and free()(including the overloading of the new and delete operators) and stuffing them in a DLL that is linked to not only the main program but also to all the plugin DLL''s. Then with some preprocessor magic I reroute calls to the basic memory reservation functions to the ones in the DLL. That way whenever I reserve memory, the functions from the DLL are used and ALL reserved memory comes from the same heap! The same goes for releasing that memory. This makes it possible to share memory across all modules in your program and not having to worry about releasing bad memory.
First of all, you CAN export classes from DLLs but different compilers use different mangling algorithms so its not easy (if not impossible) to import them from programs built with other compilers.

I would recommend exporting a "factory function", much like the way COM works.
All the client application (DLL user) needs to know is the interface to the class that factory function exports.


  //--------------------------------------------------// rendersystem.h (DLL and CLIENT)//--------------------------------------------------class RenderSystemInterface{public:   virtual const int ....};//--------------------------------------------------//--------------------------------------------------// ogl_rendersystem.h (DLL - oglrs.dll)//--------------------------------------------------#include "rendersystem.h" // function allocates an OGL rendersystem and assigns it// to parameter passed to functionextern "C" __declspec(dllexport)int createRenderSystem(RenderSystemInterface **);class OGLRenderSystem : public RenderSystemInterface{public:   virtual const int ....};//--------------------------------------------------// d3d_rendersystem.h (DLL - d3drs.dll )//--------------------------------------------------#include "rendersystem.h" // function allocates an D3D rendersystem and assigns it// to parameter passed to functionextern "C" __declspec(dllexport)int createRenderSystem(RenderSystemInterface **);class D3DRenderSystem : public RenderSystemInterface{}//--------------------------------------------------// client.cpp //--------------------------------------------------  // load the DLL, in this case either the DLL implemented // with D3D or the DLL implemented with OGL  HMODULE hMod = LoadLibrary("d3drs.dll");  RENDERSYS_CREATEFUNC pCreateFunc; RenderSystemInterface * pInterface;  // export the factory function from the DLL pCreateFunc = (int(*)(RenderSystemInterface**))GetProcAddress(hmod, "createRenderSystem");   // invoke and let DLL allocate the RenderSystem that it // corresponds to pCreateFunc(&pInterface);   


Hope you''ll get the point, there are most likely lots of typos in what I''ve written above but I''m in a hurry so this was written in 2 minutes )

/ Tooon
There is actually an article about this here at gamedev.. Pretty usefull if you ask me.. Check it out

http://www.gamedev.net/reference/articles/article928.asp
sysmark thank you for that bit of information. It will most likely be very helpful later in the development.

Tooon I can''t thank you enough for the helpful responce. You pretty much answered my question. I''ve skimmed the code you wrote a little and will go over it more later. Thanks!

Rickmeister thanks for the link. I actually already read and am still trying to understand that article. I had hoped making this thread would offer some answers to my questions. Thanks!
-- Ivyn --
I am using the same method for my game engine, and the way I handle it has already been mentioned;

Simply do this:

class __declspec(dllexport) MyClass
{
}

And then in the header file for the project using the DLL, put dllimport instead.

Michael Bartman
Michael BartmanLead ProgrammerDark Omen Studios
quote:Original post by TheRealBartman
I am using the same method for my game engine, and the way I handle it has already been mentioned;

Simply do this:

class __declspec(dllexport) MyClass
{
}

And then in the header file for the project using the DLL, put dllimport instead.



If I remember correctly, and take heed - I might not, that will load the DLL at load-time, always. I.e. you''ll have dynamic-binding but not so dynamic, or late, as you''d like. I.e. you have to specify, at link-time, what DLL''s will be loaded - which is probably not what the poster wants. The whole idea usually is to be able to choose one of several different DLL''s and load one (or not all, at least) at run-time depending on the users configuration - or even swap implementations (i.e. different implementations implementing the same interface) during execution.

I think, if I remeber correctly, you could use LoadLibrary() and GetProcAddress() to attain the address of a function for returning or creating an object of the wanted class.
By using LoadLibrary() instead of "static" linkage against the DLL you make sure you can really reap the benefits of using DLLs.

Besides, __declspec(...) is an un-portable Microsoft extension, and thus should, if possible, be avoided at any cost

This topic is closed to new replies.

Advertisement