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