Howto make an instance of a class defined in a DLL

B

Bernd Muent

Hi together,
I made a DLL in the following way (simplified example just to explain
what is the problem) using devcpp and gcc compiler on Windows XP:
dll.h:
#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */

class DLLIMPORT DllClass
{
public:
DllClass();
virtual ~DllClass(void);
void testVoid();
};
-------------------------------------------------
dll.cpp:

#include "dll.h"
#include <windows.h>
#include <iostream>

DllClass::DllClass() {}
DllClass::~DllClass () {}
void DllClass::test() {
printf("testFunction called!\n");
}

BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is
being called. */ ,
LPVOID reserved /* Not used. */ ) {
return true;
}
-------------------------------------------------

So far, so good, I could compile it with gcc and got a dll.dll as output.
dumpbin /exports dll.dll gives the following output:
ordinal hint RVA name

1 0 000011D0 _Z5testFv
2 1 000011F0 _ZN8DllClass4testEv
4 2 00001250 _ZN8DllClassC1Ev
5 3 00001230 _ZN8DllClassC2Ev
6 4 00001290 _ZN8DllClassD0Ev
7 5 00001280 _ZN8DllClassD1Ev
8 6 00001270 _ZN8DllClassD2Ev
9 7 00041C9C _ZTV8DllClass

So, the Class and ist included void are exported.
[Question beside: Why have the symbols such cryptic names. Do I have any
influence to rename them just to "DllClass" etc.?]

No I made a host application:
main.cpp:
-------------------------------
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include "dll.h"

using namespace std;

int main(int argc, char *argv[]) {
HMODULE hMod = LoadLibrary("dll.dll");
if (hMod==NULL) {printf("DLL NOT LOADED\n"); return 1} else printf("DLL
LOADED\n");

DllClass *pDllClass = (DllClass *) malloc (sizeof (DllClass));
if (NULL == pDllClass) {printf ("Memory allocation failed\n");return 1;}
else printf("Memory allocated\n");

typedef void (WINAPI * PCTOR) ();
PCTOR pDLLClass = (PCTOR) GetProcAddress (hMod, "_ZTV8DllClass");
if (NULL == pDLLClass) {printf ("GetProcAddress failed\n");} else
printf ("DLL ProcAddress success\n");
-------------------------------------
But now? How to make an instance of this class?
I found this hint:
https://secure.codeproject.com/dll/classesexportedusingLL.asp
__asm { MOV ECX, pDLLClass }
pDLLClass();

But the assember syntax is for Visual C++, not working with gcc.
I tried:
asm("MOV ECX, pDLLClass");
But this does not compile:
"too many memory references for `mov'"

Sorry, I've got no experience in programming assembler on a X86 machine,
the last time I did assembler programming was on a ZX81 von VC 64 some
20 years ago ;-)

Thank you for any tips how to get an instance of a class which is
defined in a dll, Bernd

--
Bernd Münt Durchwahl: 030/69032-509
euroscript Deutschland GmbH Zentrale: 030/69032-300
Abteilung IT-Management Fax: 030/69032-505
Alt-Moabit 91 Mail: (e-mail address removed)
10559 Berlin Web: http://www.euroscript.de
 
B

benben

[snip]
But now? How to make an instance of this class?
[snip]

Your problem will be much better addressed in other dedicated newsgroups
such as microsoft.public.vc.*

There are a number of solutions in my mind but bothering assembly is the
least you should try. So don't do it.

You can add another function in your DLL that instantiates the class and
returns a pointer to the instance. Make sure you use extern "C". In the
client code all you have to do is to call such a factory function to get
a pointer to an instance.

You probably need to provide another function for memory reclamation.

Ben
 
B

Bernd Muent

benben said:
Your problem will be much better addressed in other dedicated newsgroups
such as microsoft.public.vc.*

No. I wrote that I am using devcpp with gcc on windows. The only example
I found was for MSVC.
There are a number of solutions in my mind but bothering assembly is the
least you should try. So don't do it.

That's my opion too.
You can add another function in your DLL that instantiates the class and
returns a pointer to the instance. Make sure you use extern "C". In the
client code all you have to do is to call such a factory function to get
a pointer to an instance.

Ok, I did it that way:
dll.h:
extern "C" DLLIMPORT DllClass* createDllClass();

dll.cpp:
DllClass* createDllClass() {
return new DllClass;
}

In the program using the dll:
typedef DllClass* (*PCreate) ();
PCreate createDC=(PCreate)::GetProcAddress (hMod,"createDllClass");
DllClass *pD=createDC();
if (cD) printf("Pointer\n");

That's working, I got a pointer to the newly created instance of the class.

And then further testing:
printf("var: %d\n",pD->var);

That's working, too. "var" is declared as an public integer var in the
class.

But now:
pD->test();

This does compile but the linker complains about an unresolved symbol to
the void test.
OK, as far as I understand: the library is loaded at run time and then
this symbol will be there. But not at link time.
As far as I know, gcc is not able to create something like a static
library ".lib" to use at link time.
What to do?

I also tried:
void (FAR __stdcall *(test))()=NULL;
test = (void (__stdcall *)())GetProcAddress (hMod,"_ZN8DllClass5testEv");
test();

But this is obviously not the pointer to the function inside the
instance. This is something like a pointer to a static member of my test
class similar to DllClass::test(); And this will not work. If there is
something like "var+=10;" inside the function test, the program crashes
becauce there is no memory allocated.

You probably need to provide another function for memory reclamation.

How? Can you give me an example?

Greetings, Bernd
 
R

red floyd

Bernd said:
No. I wrote that I am using devcpp with gcc on windows. The only example
I found was for MSVC.

Your argument is equivalent to:

"I went to the butcher, looking for fresh apples. They told me to go to
the fishmonger. The fishmonger didn't have apples, so I came back to
the butcher."

Try gnu.g++.help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top