link from a dll to another function in another dll?

Rainer Schuetze r.sagitario at gmx.de
Sat Apr 30 05:06:42 PDT 2011


I'm not sure your wrapping will work with kernel32.dll, but in general 
here are a few tips:

- most functions in the windows API use the __stdcall calling convention 
in C/C++, which translates to D as "extern(Windows)"

- this will usually add the number of bytes passed on the stack as a 
"@NN" postfix to the function name. This postfix does not exist in 
kernel32.dll, but in the import library kernel32.lib that you find in 
the dmd lib folder. Maybe you can use the standard import library, or 
use the translation shown below.

- as the exported function and the function you want to chain to have 
identical names, you have to change at least one of these and modify 
them in some build step. I'd suggest to do this in the def file:

The symbols in the d-source file containing:

----
extern(Windows) HANDLE imported_GetCurrentProcess();

export extern(Windows) HANDLE internal_GetCurrentProcess()
{
   return imported_GetCurrentProcess();
}
----

can be mapped to other symbols in the def file:

----
EXPORTS
   GetCurrentProcess = internal_GetCurrentProcess

IMPORTS
   imported_GetCurrentProcess = kernel33.GetCurrentProcess
----

- if you don't know the number of arguments, you should not call the 
wrapped function, as this will change the callstack. Instead, you should 
just jump to it:

void internal_hread()
{
   asm
   {
     naked;
     jmp imported_hread;
   }
}

I haven't tried all that, though, so there might be some mistakes...

Rainer


Denis Koroskin wrote:
> On Sat, 30 Apr 2011 13:47:53 +0400, maarten van damme 
> <maartenvd1994 at gmail.com> wrote:
> 
>> I've changed this, I think I'm still kinda confused with lib files. 
>> They've
>> told me you can't do something with them without a .di file
>> So I went ahead and made a kernel33.di file. I now import it in 
>> kernel32.d
>> and my declaration is
>> System(C){
>> export void * exportedfunctionblablabal(){
>>    return exportedfunctionblablablal();
>> }
>> ...
>> }
>>
>> The file in the directory are:
>> kernel32.d : http://dl.dropbox.com/u/15024434/d/kernel32.d
>> kernel33.di : http://dl.dropbox.com/u/15024434/d/kernel33.di
>> kernel33.lib : http://dl.dropbox.com/u/15024434/d/kernel33.lib
>> kernel33.dll : http://dl.dropbox.com/u/15024434/d/kernel33.dll
>>
>> I've tried to compile using dmd -d kernel32.d kernel33.di kernel33.lib 
>> but
>> it throws errors like
>> "Error 42: Symbol undifined _Dkernel1336_hreadfzpV"
>> I have literally no clue why this is the case, can someone help me out or
>> look at the files?
>>
>> 2011/4/27 maarten van damme <maartenvd1994 at gmail.com>
>>
>>> I'm afraid I've been a little unclear.
>>> I've copied kernel32.dll from the windows dir, renamed it to 
>>> kernel33.dll
>>> and generated a .lib from it using implib.
>>> Then I've created a d file with a correct dllmain(stolen from 
>>> examples) and
>>> between
>>>
>>> system(C){
>>> export void * exportedfunctionfromkernel33.dll();
>>> export void * exportedfunction2fromkernel33.dll();
>>> ...
>>> }
>>>
>>> But it looks like you can't both declare a function from another lib and
>>> export it at the same time.
>>>
> 
> In your kernel33.di, try making it extern (C) export void* _hread(); 
> etc. You functions get D mangling otherwise.
> 
> I'd also suggest you to start with a less complex example, e.g. export 
> only one function, make sure it works, then add the rest.
> 
> If you think your .lib files doesn't do its job, try using .def file 
> instead. I find them extremely helpful, and they are a lot easier to 
> edit/extend.
> 
> Hope that helps.


More information about the Digitalmars-d mailing list