dll help visual C++ 6.0

Started by
19 comments, last by kindfluffysteve 20 years ago
Hello, could somebody please explain to me how to put class methods into a .dll? My situation is this. I''m writing a flightsim, and want to enable the possibilities of bright users to modify some sort of cockpit .dll my sim runs as a win32 console app using glut. I have ofcourse tried googling for hours and never really quite getting the answer I''m after - Its easy to stick c functions into a dll, but the rest - I''m having some difficulty with. http://www.thunder-works.com
Advertisement
Funny thing i was just looking at this, but i was looking at run-time loaded dlls. anyway check this out

edit: spelling


[edited by - TheNamelessOne on September 2, 2003 12:52:05 AM]
quote:Original post by TheNamelessOne
Funny thing i was just looking at this, but i was looking at run-time loaded dlls. anyway check this out

edit: spelling


[edited by - TheNamelessOne on September 2, 2003 12:52:05 AM]


That code in the URL you gave has some flaws (the kind of flaw that leads to a crash).
quote:Original post by mputters
That code in the URL you gave has some flaws (the kind of flaw that leads to a crash).


It was really more for the concept, but here''s working code for visual c++ 6.0.

FooInterface.h
//-------- FooInterface.h --------//#ifndef FOOINTERFACE_H#define FOOINTERFACE_Hclass IFoo{public:	virtual int GetNumber() = 0;	virtual void SetNumber( const int & ) = 0;};#endif	// FOOINTERFACE_H 


FooClass.h
//-------- FooClass.h --------//#ifndef FOOCLASS_H#define FOOCLASS_H#include "FooInterface.h"class FooClass ublic IFoo{public:	FooClass();	virtual int GetNumber();	virtual void SetNumber( const int & );private:	int number;};#endif 	// FOOCLASS_H 


FooClass.cpp
//-------- FooClass.cpp --------//#include "FooClass.h"FooClass::FooClass(){	number = 0;}int FooClass::GetNumber(){	return number;}void FooClass::SetNumber(const int &arg){	number = arg;} 


DllMain.cpp
//-------- DllMain.cpp --------//#define __dll__#include "DllExports.h"#include <windows.h>IFoo* TheFoo = NULL;int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*){        return 1;}IMPEXP void* CreateFooClassInstance(){	TheFoo = (IFoo*)new FooClass;	return (void*)TheFoo;}IMPEXP void* DeleteFooClassInstance(){	delete TheFoo;	return NULL;} 


DllExports.h
//-------- DllExports.h --------//#ifndef DLLEXPORTS_H#define DLLEXPORTS_H#ifdef __dll__#define IMPEXP __declspec(dllexport)#else#define IMPEXP __declspec(dllimport)#endif 	// __dll__#include "FooClass.h"extern "C" IMPEXP void* CreateFooClassInstance();extern "C" IMPEXP void* DeleteFooClassInstance();#endif	// DLLEXPORTS_H 


ExeMain.cpp
//-------- ExeMain.cpp --------//#include "FooInterface.h"#include <windows.h>#include <iostream.h>#include <conio.h>typedef void* (*pvFunctv)();int main(int argc, char* argv[]){	HINSTANCE hdll = NULL;	IFoo* piFoo = NULL;	pvFunctv CreateFoo;	pvFunctv DeleteFoo;	hdll = LoadLibrary("FooDll.dll");		// load the dll	CreateFoo = (pvFunctv)GetProcAddress( hdll, "CreateFooClassInstance" );	piFoo = (IFoo*)CreateFoo();	// get pointer to object	piFoo->SetNumber(8);				// start using the object	cout 	<< "Foo::number is epual to: "		<< piFoo-> GetNumber()		<< endl;	cout	<< "Enter new value for Foo::number: ";	int temp;	cin	>> temp;	piFoo->SetNumber(temp);	cout	<< "Foo::number is now: " << piFoo->GetNumber()		<< endl;	getch();	DeleteFoo = (pvFunctv)GetProcAddress( hdll, "DeleteFooClassInstance" );	DeleteFoo();				// delete the object	piFoo = NULL;	FreeLibrary(hdll);				// free the dll	return 0;} 



typedef void* (*pvFunctv)();

Can someone explain to me what that line does exactly?

I know its a typedef for a void pointer, but I can''t figure out what the (*pvFunctv)() part does. Thanks!

Greetings,

TjoekBezoer
Greetings,TjoekBezoer
It declares a typedef for a pointer to a function that takes no arguments and returns a void * pointer. By casting the result of GetProcAddress() to a pvFunctv, you can call the function pointer like a function that shares its signature.
Ok thanks

But now, I am experimenting some myself. I am trying to load a dll with one non-virtual class in it.

The class alone works, no problems with it, but as soon as i call it in my main program i get linking errors (unresolved symbols when calling methods)

Part of my main code:

typedef void* (*voidFunc)();void main() {	HINSTANCE handle;	Stack* myStack;	voidFunc CreateStack;		handle = LoadLibrary("DevCentral CInDLL.dll");	CreateStack = (voidFunc)GetProcAddress(handle, "returnStackPtr");	myStack = (Stack*)CreateStack();	int intResult;	myStack->Push(5);	myStack->Pop(intResult);	cout << intResult;}  


So i try to call returnStackPtr from my DLL, which looks like this:
DLL_API void* returnStackPtr() {	Stack* ptrStack = new Stack(10);	return static_cast(ptrStack);}   


DLL_API being dllexport in this case.

During the linking process I get these errors:
main.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Stack::Pop(int &)" (?Pop@Stack@@QAE_NAAH@Z) referenced in function _mainmain.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Stack::Push(int)" (?Push@Stack@@QAE_NH@Z) referenced in function _main  


My problem is that I don't see what I am doing wrong

Thanks for your help

Greetings,

TjoekBezoer

[edited by - tjoekbezoer on March 31, 2004 7:55:41 PM]

edit(AR): don't stretch the tables, thanks.

[edited by - Andrew Russell on April 1, 2004 7:39:08 AM]
Greetings,TjoekBezoer
You are including the header file in main()''s .cpp file?
Mmmm...

Class Methods in dlls...

The BEST way is to define your class as a COM class!!!

COM... and other COM based languages like DCOM, are, believe it or not, the ultimate examples of FULLY Object Oriented Programming (OOP).

By the way, I say language.... Well, you could use the Interface Defintion Language IDL, which COM is based on... Using that will even allow you to write class dlls for other languages such as Visual Basic, Java and Pascal etc etc...

But if you''re language platform is strictly C / C++... Then you don''t even have to learn IDL... Simply sprinkle your C++ code with some COM runtime functions and you are away!!!

I cannot emphasize just what an impact COM based dll programming has had on me. It REALLY is what C++ should have been. You know, encapsulation, black box component technology, plug ins etc etc...

With COM based dlls....You can change the class completely... even change the number or order of class members... so long as the class interface remains static... You can totally rewrite the class dll... And if you wish to add new features... COM can do that too...

Anyway, I''m waffling (COM is like a religion to me)... If you''re
REALLY interested in writing totally upgradeable class dlls in C++... COM.... or a COM based approach IS the ONLY way to go...

Here''s a book which really made me see the light in the REAL power of distributive programming:

Essential COM: By Don Box

It shows you WHY COM was invented, to solve problems like sharing class dlls between programmers and users alike... And then takes you through SIMPLE steps towards building your own COM based dlls...

Anyway, check it out man!!! The book won''t take more than a few weeks to read... And to be honest... chapters 1 - 3, 4 is all you really need to write COM based dlls.

And remember... DirectX, OpenGL, and countless other APIs are infact COM based...

If you want to know more... I''ll send you my email...

Hope this helps!!!
quote:Original post by TjoekBezoer
But now, I am experimenting some myself. I am trying to load a dll with one non-virtual class in it.

Think about it for a moment. You''ve gotten a pointer to an object, and you''re trying to call a non-virtual function. That means the class''s member function implementation needs to be known at link time. However, you''re trying to put the implementation of the class in a DLL that you load with LoadLibrary(), which means that the class''s member function implementation doesn''t get loaded until runtime. These are two incompatible situations.

You should either use an abstract interface class as shown in the post above, or you need to do a link time specification of the DLL, in which case you can bind a non-virtual function to a dll procedure properly. (i.e. use __declspec(dllexport) on the class instead of the factory methods and specify the dll in your linker settings.)

This topic is closed to new replies.

Advertisement