Question on DLL example

Mike Parker aldacron71 at yahoo.com
Wed Nov 8 04:38:41 PST 2006


Nox / Lux wrote:
> Hello all,
> 
> I have been trying out the "Win32 DLLs in D" example found at
> http://www.digitalmars.com/d/dll.html (the "D code calling D code in DLLs"
> section), and now I have many questions :)
> I am trying to figure out how a plugin system could be written in D.
> 
> Heh, the first thing that strikes me about the example is that there are quite
> a few things I don't understand. Like what is "HINSTANCE g_hInst;" and what
> does it mean?

HINSTANCE is a type definition from the Win32 API, which means 
essentially "instance handle". Win32 is a C API that hides the actual 
implementation of data structures behind HANDLE types. Every application 
that runs on Windows is assigned an instance handle of type HINSTANCE. 
Some Win32 API calls require this handle to be passed as an argument. If 
you don't need to call Win32 or setup DirectX or anything, then you 
don't need to worry about it.

> 
> What does
> "extern (C)
> {
> 	void gc_init();
> 	void gc_term();
> 	void _minit();
> 	void _moduleCtor();
> 	void _moduleUnitTests();
> }"
> do and why is it contained within extern (C)? Isn't this D code interfacing
> with D code?

These functions are part of the bootstrap code that launches every D 
application. It is all implemented in C, not in D. Every D application 
must call these functions in order to operate properly. When using a 
main() method, this is done automatically for you (look in 
dmd/src/phobos/dmain2.d for the implementation -- this is the real app 
entrypoint function that is executed from C code before your D main 
function is ever called). When using WinMain, you are creating the 
acutal entry point and bypassing the default bootstrap code, so you are 
responsible for calling all of the C bootstrap stuff yourself.

> 
> What does
> fp = GetProcAddress(h, "D5mydll16MyDLL_InitializeFPvZv");
> do, and why is the second argument a mangled name?

GetProcAddress is a Win32 API function that returns a pointer to a 
function in a DLL. Normally, when linking with an import library on 
Windows the DLL is imported into the application's memory space for you 
automatically. But an API also exists for you to do the same thing 
manually, and that is what is happening here.

The mangled name is the name of the function as it appears in the DLL. 
If you were to declare a D function as "extern C", it would use a 
different form of mangling. In this case, MyDLL_Initialize has D linkage 
(i.e. the default extern(D)) and therefore uses D mangling. When 
fetching a function pointer from a DLL using the GetProcAddress, you 
must know the mangled function name. It is possible to create aliases 
for DLL function names via a DEF file.

> 
> Also I noticed that if I copied the code of mydll.d into a second file and
> named it "mydll2.d", test.d would fail to run it after I compiled it to
> "mydll2.dll". It would fail "MyDLL_Initialize()" ("error loading symbol
> MyDLL_Initialize()"). But if the source file is named mydll.d, compiled and
> then simply renamed to mydll2.dll, test.d will load it without problem. Why is
> that? It is not very versatile of a program only to accept a plugin compiled
> under a certain name - I would like a more general solution. Is that possible,
> possible but complicated or impossible?

It's because of D's name mangling. The module in which a method appears 
is included in the mangled name. Notice the first part of the mangled 
function name: D5mydll. See the mydll there? The source file 'mydll.d' 
is the module 'mydll'. The source file 'mydll2.d' is the module 
'mydll2'. So when you compiled mydll2.d, the mangled name in the DLL 
changed ('D5mydll' would be replaced by 'D5mydll2'). You didn't change 
the name of the function you were trying to load, so the call to 
GetProcAddress failed.

The inclusion of module names in mangled function names makes it 
impossible to implement a generic plug-in system by loading mangled 
functions. I've never used D DLLs before, but I've used them in C a lot. 
I expect that if you research .def files and function name aliases, you 
should be able to cobble together a solution.

If you want a premade solution, you might want to check out the DDL (D 
Dynamic Libraries) project at dsource.org.

> 
> I realize by now that it probably would be good idea to read up on how DLLs
> work in general. Does anyone have any tips on where (websites, books) I could
> find an introduction to this?

You might start at MSDN (Microsoft Developer Network) and the Knowledge 
Base there: http://msdn2.microsoft.com/en-us/default.aspx. Also, Charles 
Petzold's book "Programming Windows, 5th Edition" has a section on DLLs. 
That's a big book to buy just for the one section though, so I'd only 
recommend it if you are interested in learning Win32 programming in 
general. It's an excellent source for doing so. Otherwise, I can't think 
of any online DLL resources off the top of my head. See what Google 
tells you.



More information about the Digitalmars-d-learn mailing list