Re: link from a dll to another function in another dll?
Rainer Schuetze <r.sagitario <at> gmx.de>
2011-05-01 16:48:23 GMT
It seems you have hit another of those dreaded optlink bugs.
With less symbols, it works if you declare the imports like this
(because of the described name mangling):
IMPORTS
_imported_hread <at> 0 = kernel33._hread
2 more notes:
- you don't need to import kernel33.di
- you should not use "SINGLE" in the DATA statement of the def file, it
will share the memory across processes.
maarten van damme wrote:
> Number overflow?
> So I implemented the suggested changes (you can check them out
> at http://dl.dropbox.com/u/15024434/version2.zip)
> But now I get when I compile it :
> "kernel32.def(738) : Error 12: Number Overflow: (strange symbol over here)"
>
> I do agree I should've picked a simpler example but I think the
> statisfaction will be even bigger if I were to succeed :p
>
> 2011/5/1 maarten van damme <maartenvd1994 <at> gmail.com
> <mailto:maartenvd1994 <at> gmail.com>>
>
> Wow, thanks for the help
> The first thing I did was in the .di file adding extern(windows){ ... }
> and now compiling doesn't give errors and when examining with dllexp
> I can see that it exports the same functions as the real kernel32.dll :D
>
> Now I'm going to implement all other suggested changes, thanks a lot
>
>
> 2011/4/30 Rainer Schuetze <r.sagitario <at> gmx.de
> <mailto:r.sagitario <at> gmx.de>>
>
> 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 " <at> 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 <mailto: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
> <mailto: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.
>
>
>