|
How can I load a DLL with classes at runtime?
|
|
|
|
|
Verifier wrote: How can I load a DLL with classes at runtime?
No U cannot, actually Class function get it address only when there Object is created!.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
Hi all,
I am a new DLL user of VC7.0 (VC++ .NET 2002)on Windows XP Pro PC and I do not know how to use the .cpp and .h files of Husain's DllTest and DllTestApp to create DllTest.dll and DllTest.lib. Please help and give me some detailed instructions for creating the DllTest.dll and DllTest.lib on the Win32 project of VC++ .NET 2002.
Thanks in advance,
Scott Chang
|
|
|
|
|
Err... VC7.0 can import/open VC6.0 projects out of the box, so you should not have any problem opening the existing example.
Regards,
TH
|
|
|
|
|
is it mean that regular DLL can replace extension DLL every time?
dd
|
|
|
|
|
I don't think this has been made clear: for the exporting DLL, the class name must be prefixed by
__declspec(dllexport)
and for the importing DLL / EXE, prefixed by
__declspec(dllimport)
hence the AFX_EXT_CLASS macro, which is defined as one or the other accordingly. If you don't do this, the export won't work properly.
So, how do you make this work? Simple, define a symbol in your DLL (say _MYDLL), derived from the name, that will only be defined in the DLL. Then define another symbol (say EXPORT_FROM_MYDLL) which is defined as __declspec(dllexport) when _MYDLL is defined, and __declspec(dllimport) when it's not. Put the second symbol before the class name in the header that you export to clients.
Here's the scheme, wrapped up in a header (MyDLLExport.h) which you should #include in all headers which clients see (all exported class headers). It also auto-includes the lib for clients, which is another very handy idea I came across recently.
#ifndef MYDLLEXPORT_H
#define MYDLLEXPORT_H
#ifdef _MYDLL
#define EXPORT_FROM_MYDLL __declspec(dllexport)
#else
#define EXPORT_FROM_MYDLL __declspec(dllimport)
<p>
#ifndef _UNICODE
#ifdef _DEBUG
#pragma comment (lib, "MyDlld.lib") // Include ANSI debug MyDll lib
#else
#pragma comment (lib, "MyDll.lib") // Include ANSI release MyDll lib
#endif
#else
#ifdef _DEBUG
#pragma comment (lib, "MyDllud.lib") // Include Unicode debug MyDll lib
#else
#pragma comment (lib, "MyDllu.lib") // Include Unicode release MyDll lib
#endif
#endif
#endif
#endif
The whole business of not being able to export classes from regular DLLs is a huge myth. I've been doing it for years without a problem. I do sometimes get a couple of warnings about classes "not having a DLL interface" though, which I disable with a pragma:
#pragma warning( disable : 4251 4275 )
I don't know if some terrible doom awaits me for doing this, but nothing's happened so far.
|
|
|
|
|
I created a MFC class like you described and tried to insert it to C# project, but I didn't know how to insert it in c# project.
If you can, please give some examples that describe it.
|
|
|
|
|
Er... I'm afraid I have no clue on C#... haven't even played with VC.Net yet...just installed it and left it to rot
Tanzim Husain
|
|
|
|
|
It's not possible to import a general C++ class to C#, and, correct me if I'm wrong, this include MFC classes, too.
In C# you can only import standard C functions using the DllImport attribute before declarating an extern function.
--------------------------
xplo.re Project Management
http://xplo-re.com/
http://koushiro.de/
|
|
|
|
|
It is, however, possible to refactor your C++ dll with Managed Extensions, either by making it directly useable by .NET classes, or by creating .NET-friendly wrapper classes that manipulate the existing C++ objects in the appropriate way. When someone mentions C# though, I get the idea that they're trying to get Windows.Forms and MFC to play together, and the implications of that make the hairs on the back of my neck stand up.
|
|
|
|
|
I know that I should use #pragma comment(linker, "/export:DoSomething=DllImpl.ActuallyDoSomething")
But I have not any explication for it
Thanks
|
|
|
|
|
U should go for dll code injection for stuff like that
Jeffery Richter's Advanced Windows Programming has some nice information on it.
Tanzim Husain
|
|
|
|
|
on 5 Mar '03 bfadi wrote:
I know that I should use #pragma comment(linker, "/export:DoSomething=DllImpl.ActuallyDoSomething")
But I have not any explication for it
This is a little late perhaps,
but
try here for #pragma comment[^]
see here for linker options[^]
Incase the links don't work. I cut the relevant bits from MSDN:
#pragma comment( comment-type [, commentstring] )
Places a linker option in the object file. You can use this comment-type to specify a linker option instead of placing the option on the Link tab of the Project Settings dialog box. For example, you can specify the /include option to force the inclusion of a symbol:
#pragma comment(linker, "/include:__mySymbol")
Syntax
/EXPORT:entryname[=internalname]
With this option, you can export a function from your program so that other programs can call the function. You can also export data. Exports are usually defined in a DLL.
The entryname is the name of the function or data item as it is to be used by the calling program. You can optionally specify the internalname as the function known in the defining program; by default, internalname is the same as entryname.
So you can see that by redefining the internalname to be a call to a function exported by another dll, you can have your wrapper dll export the interface of the other dll(or part of it).
|
|
|
|
|
Thanks very much for the answer , its NOT too late. Its just on time
I have more questions if you have time to help me please.
How can I know the argument of a function exported from a DLL ???????
Like the functions exported from NTDLL.DLL like NTDeleteFile
This function not fount in the DDK ?
Thanks very very much
|
|
|
|
|
I'm afraid that's a bit beyond me to answer.
I can tell you there is no easy was to find out if a function signature
is not documented, what the return type and args are. I think it is usually done by stepping through an assembly at the point of the call and making an educated guess, then testing it.
With regard to NTDLL.DLL if you were just interested in the undocumented
API for this dll in particular you are in luck as it has mostly been revealed at
ntinternals.net[^]
For native API you could start at sysinternals.com[^]
For more dynamic API interception the
Detours[^]
library looks very useful, but one has to know the function signatures.
sorry I can't help any more than this.
|
|
|
|
|
Thanks very much
Fadi
|
|
|
|
|
Are you sure you are really linking dynamically against
the DLL, rather than statically against the LIB?
I downloaded your sample project and looked at your code.
In your DllTestApp.dsp there's a line like this for each
build configuration:
# ADD LINK32 ..\DllTest\Debug\DllTest.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\DllTest\Debug"
Naively it looks to me like it's statically linking
against DllTest.lib. I can see that using _declspec
(dllexport) in a class declaration does export everything
from the DLL. But what are you doing to import from the
DLL, besides including the DLL's header file in your
application?
I'm still looking for a way I can export C++ classes from
a DLL and import them into any C++ application.
Otherwise, for the projects I need to develop, it's
almost pointless to use MFC or C++ at all.
|
|
|
|
|
Yes as I can see it´s static. If you look in Project->settings->Link for the program you find this Link under "Object/LibraryModules" ..\DllTest\Debug\DllTest.lib
I am also looking for a nice way to export classes from a DLL (None MFC:s).
It can be done with a wrapper class, but still there must be a better way of doing this... To be cont.....
Jontemannen
|
|
|
|
|
As far I know it is possible to load a class dynamically, but this would mean, you must allocate your own class object at runtime and find a way to handle it. For importing those methods you may use the C++ encoded method name which looks like "??2@YAPAXI@Z" (in this case it's an exported new-operator in global namespace).
But it seems quite complex, so maybe you'd prefer to create a general wrapper class or an interface-like structure (like DirectX does, for example), or create you own reflection API.
If you find a good way.. tell us -.^
--------------------------
xplo.re Project Management
http://xplo-re.com/
http://koushiro.de/
|
|
|
|
|
when compiling the application, use the same header for the class, but instead of using __declspec(dllexport), use __declspec(dllimport)
|
|
|
|
|
Very useful project - thanks.
Could you explain how multiple classes can be included in your project? Also, for a new comer to DLL's could you explain how I tell my program which DLL's to load? Sorry if these questions are too basic
Graham W Griffiths
|
|
|
|
|
You can include as many classes as you want!
All you do is, use the __declspec(dllexport) before the class name, like..
class <pre>__declspec(dllexport)</pre> MyClass {
};
To load a dll, you have to link your application with the dll. The easiest way to do that is to link to the dll's lib file. Just check the sample application.
In the Project Settings->Link->Input, specify the name of the lib file, like in the demo project of the article, that's it!
Regards.
Tanzim Husain
|
|
|
|
|
Can this be done to VB6? Pardon my bliss, but I really don't know how one would start passing an object from a C++ DLL (MFC or otherwise) to a VB object. Might anyone know if this is possible one way or another?
|
|
|
|
|
No. You must use COM in order to do this. The other alternative is to export C functions. C++ uses mangled names and this is C++ compiler-specific and is not recognized by VB.
gs
|
|
|
|
|
Yeah, I got a little further into this problem and ended up making an ATL dll, which worked. So, as you already know, you're right about this. COM i/f here or nuthin.
|
|
|
|