Archived

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

Dwiel

Classes in dll

Recommended Posts

I was wondering how to have a class in a dll and then load the dll or just link to it through the lib file created. When I just use functions, everything works OK because MSVC++ gives me a lib file I can include in main exe, but when I use a class, it doesn''t work this way. I get no lib file. What''s going on? I have my functions like this:
  
#ifndef _DLLTEST_H_
#define _DLLTEST_H_

#include <iostream.h>
#include <stdio.h>
#include <windows.h>

/*
extern "C" __declspec(dllexport) void NumberList();
extern "C" __declspec(dllexport) void LetterList();
*/

class Stuff
{
public:
	void NumberList();
	void LetterList();
};

#endif
  

  
#include "dll test2.h"

#define MAXMODULE 50

char module[MAXMODULE];
/*
extern "C" __declspec(dllexport)

void NumberList() {

//do stuff

}

extern "C" __declspec(dllexport)

void LetterList() {

//do stuff

}
*/

extern "C" __declspec(dllexport)
Stuff stuffer;

void Stuff::NumberList() {

//do stuff


}

void Stuff::LetterList() {

// do stuff


}
  
btw, this is directly from a tutorial on flipcode tazzel3d ~ dwiel

Share this post


Link to post
Share on other sites
I couldn''t find any posts that answered my question all the way back to October 19th.

would soeone be kind enough to post a very short exaple of what is in the cpp and h files?

thats all I need....

please...

maybe soething like what''s in my code above, but even shorter?

thanx a lot for whoever helps !

tazzel3d ~ dwiel

Share this post


Link to post
Share on other sites
If you are using MSVC++ create a new dll project. In the wizard select the option “Export some symbols”. This will create some example code that exports a variable a function and a class. Hope this helps

Share this post


Link to post
Share on other sites
Hey,

I ran into a similar problem a while back. What you need to do is export and import the class like this:

in the DLL:

  
class __declspec(dllexport) Stuff
{
public:
void NumberList();
void LetterList();
};

void Stuff::NumberList()
{
//do stuff

}

void Stuff::LetterList()
{
// do stuff

}


In the projects using the DLL:

  
class __declspec(dllimport) Stuff
{
public:
void NumberList();
void LetterList();
};
...
Stuff stuffer;
...


Do you get the general idea?

If not, I'll help you out some more.

Michael Bartman
Dark Omen Studios
Lead Engine Programmer


[edited by - TheBartman on November 7, 2002 1:47:07 AM]

Share this post


Link to post
Share on other sites
Ok. Thanx for the help!

I can''t test it right now because I have to go to school, but I wiill when I get back.


Thanx a lot.

tazzel3d ~ dwiel

Share this post


Link to post
Share on other sites
TheBartman''s solution will work fine, with one problem: you will only be able to use the class with the same compiler that created the DLL. If you are the only person likely to use it, that shouldn''t be a problem. However, if you want other compilers to be able to use your class, then you have to do the following:

To export the following class:

class Stuff
{
public:
void NumberList();
void LetterList();
};

Do the following:
(1) Create the following class:
class StuffInterface
{
public:
virtual void NumberList() = 0;
virtual void LetterList() = 0;
};

(2) Then write Stuff, making sure it is derived from StuffInterface.

(3) Create a function:
extern "C" __declspec(dllexport) StuffInterface* CreateStuff()
{
return new Stuff;
}

Now, when you want to use Stuff, instead use StuffInterface*

Reason: The compiler gives any C++ function, including member functions, a horrific decorated name, specific to the compiler you are using(E.g: Stuff::NumberList will become something like ?NumberList@Stuff@@FJFA3FZ ). Any function that you want to use from another compiler must be declared as extern "C". Member functions cannot be declared in this way. However, pure virtual functions in abstract classes are only referenced as in offset into the virtual function table. Hence, the name is immaterial.

Share this post


Link to post
Share on other sites
quote:
#include "dll test2.h"


And for the love of god or whoever you want to love. DO NOT USE SPACES IN INCLUDE FILENAMES.



- Zorak - Neat Fella.

Share this post


Link to post
Share on other sites
Hey again,

sbennett is correct, my solution may not work on all compilers, but I assumed you were using MSVC++. If you aren''t using Visual C++, then I might not be able to help you because I only know MSVC++. If you still need help, I will help you out just email me.

Michael Bartman
Dark Omen Studios
Lead Engine Programmer

Share this post


Link to post
Share on other sites
Hey!

Thanx for all of the help!

I did get it working by starting with what bartan had and with what MSVC++ 6.0 gave me.

Now what I was wondering was how do, was to import any number of dlls durring run time that have unknown class names, but derived from the same, known base class?

If this doesn't make sence, I'll try explaining myself again

thanx alot!

tazzel3d ~ dwiel

[edited by - tazzel3d on November 7, 2002 6:47:45 PM]

Share this post


Link to post
Share on other sites
Hey,

I am glad that I was able to help you. I would help you with your second question, but I am not sure what you are asking.


Michael Bartman
Dark Omen Studios
Lead Engine Programmer

Share this post


Link to post
Share on other sites
Ok, here we go....

I am trying to write a basic engine that handels most of windows messages and stuff like that. Right now, I have Multipule classes with base class of Screen. Only 1 can be displayed at a time, and it handels all of the displaying and calculating of algorithms. It has:

FrameMove();
Message(UINT msg, WPARAM wparam, LPARAM lparam);
Render();
InitScene();
KillScene();
char name[32];

which are called by my main class. Every frame, FramMove() is called followed by Render(). When the screen is loaded, InitScene() is called and when closing, KillScene() is called. Message() is called whenever the main class recieves a message it thinks the screen should have. (mouse, keyboard, etc)

Now...

I want have all of my classes in dlls so that only they have to change, and the game or application or w/e is completely different. Also this way I can work on one class and not have to worry about touching the other screen's code. I can also send out new versions of each screen not each progra if I find a bug. All I have to do is send out a new dll, not a whole new installation or w/e.

How can I do this when the engine doesn't know the naes of the dlls or what the name of the class is inside?

tazzel3d ~ dwiel

P.S. I did quite a bit of rambling, but I hope I explained myself...

Thanx for the help Bartman!

P.S.S. Pardon my m's, or lack there of

[edited by - tazzel3d on November 7, 2002 8:24:00 PM]

Share this post


Link to post
Share on other sites
Hmmm, I don't know that you could do that without the engine knowing the name of the DLL at runtime somehow. The way I am doing the Dark Omen Engine is that I have a DLL with different modules aka classes that handle different portions of the engine. As long as I don't change the base classes name or a previously existing methods name or parameters, then when I update something or fix a bug all I should have to do is redeploy the DLL and not recompile code depending on those modules. That means that I have a level of reverse compatibilty with previous engine versions. I think that is the same thing that you are trying to accomplish.

And you are welcome, I don't mind helping out others when I can

ps if my sig logo works, what do you think of it?


Michael Bartman
Dark Omen Studios
Lead Engine Programmer
[IMG]http://darkomensoft.topcities.com/doslogo.jpg[/IMG]


[edited by - TheBartman on November 7, 2002 8:37:43 PM]

[edited by - TheBartman on November 7, 2002 8:38:46 PM]

Share this post


Link to post
Share on other sites
My Bad, I meant not know the name of the dll and the name of the class at compile time.

It would know the names of the dlls at runtime.

thanx

tazzel3d ~ dwiel

[edited by - tazzel3d on November 7, 2002 8:40:40 PM]

Share this post


Link to post
Share on other sites
Hey,

I don''t think so, at least not the way I am thinking. You could have a text file that has the name of the DLL that needs to be loaded and have the source open that file and check.

ps Do you know how to put images into your sig? For the life of me I can''t figure it out lol thanks

Share this post


Link to post
Share on other sites
No...I''m not sure... sorry

So If I have a file with the list of dlls that need to be opened, I can have the exe load the file and use the dlls listed in the file? all durring runtime?

sorry...
just want to get this strait

I know that programs like PJ64, an N64 emulator, have a menu that let you choose what plugin ( dll ) you want to use so there has to be a way...

maybe not

*sigh*

tazzel3d ~ dwiel

Share this post


Link to post
Share on other sites
I think that those programs have those DLL''s hardcoded in, and you just pick which one you want to use and it runs the code to load that DLL and then the code uses functions for that DLL etc.
I am not an expert at that sort of thing, so I think that this stuff is over even my head.

Share this post


Link to post
Share on other sites
Yeah, thanx for your help. Now that I''m thinking about it, I can do just about as well knowing the dll name durring the compile... I just thought that it would be cleaner that way, but it would proboly take a lot of iprovising and end up not so pretty....

well, thanx for your help!

tazzel3d ~ dwiel

Share this post


Link to post
Share on other sites
A common solution is to do a directory search for .DLL, and attempt to load all of them. All that successfully loaded are offered to the user.

Allan

Share this post


Link to post
Share on other sites
quote:
Original post by TheBartman
ps Do you know how to put images into your sig? For the life of me I can''t figure it out lol thanks


<img src="url_of_image_goes_here"></img>

Html is good....

_____________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________

Share this post


Link to post
Share on other sites
Edit: Never mind, I found it. It didn't like the inline of the destroy function


I'm have made a graphic dll for use in my game and if I compile the game in debugmode everything is fine, howerver if I compile it in release mode (the dll is always compiled in release mode) it will give me a memmory can not be read error.
I have traced the error to my bitmap->Destroy() function but I can't understand why it doesn't work.


    
// The bitmap class


#ifndef _BITMAP_H_
#define _BITMAP_H_

#include "defines.h"

class DLL CBitmap
{
public:
// Constructor/Destructor

CBitmap();
~CBitmap();

// Load bitmap from file

bool Load(char *fileName);

// Write bitmap to file

bool Write(char *fileName, int width, int height);

// Take a screenshot

/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */
void ScreenShot(char *fileName, int winWidth, int winHeight);

// Draw the bitmap

void Draw(int xPos, int yPos);

// Height/Width/Bpp

int Height() { return bitmapInfoHeader.biHeight; }
int Width() { return bitmapInfoHeader.biWidth; }
int Bpp() { return colorMode * 8; }

// Image

unsigned char *Image() { return bitmapImage; }
unsigned char Image(int index) { return bitmapImage[index]; }

// Destroy

void Destroy() { free(bitmapImage); bitmapImage = NULL; }

private:
FILE *filePtr; // The file pointer

BITMAPFILEHEADER bitmapFileHeader; // Bitmap file header

BITMAPINFOHEADER bitmapInfoHeader; // Bitmpa info header

unsigned char *bitmapImage; // The image

int colorMode; // 1 == 8 bit, 2 == 16, 3 == RGB 4 == RGBA

unsigned char tempRGB; // Swap variable

};

#endif


DLL is defined as __declspec(dllexport) (or import, depending on whthere I call it from my game or not). And a creat a bitmap for loading my sprites like this: CBitmap *bitmap = new CBitmap;
It'll create and load the bitmap just fine, and I can use it for loading a sprite, but when I call on the Destroy() I gives me a memory error.
I'm using malloc() to allocate the memory for the bitmap.
Anyone got any idea of how to fix this?


Thanks

[edited by - Spearhawk on November 8, 2002 11:01:15 AM]

Share this post


Link to post
Share on other sites