View mode: basic / threaded / horizontal-split · Log in · Help
January 10, 2013
Creation of import libraries for Windows
Hi all,

This is actually a duplicate of my post on the D.learn forums :).
I am concerned that it hasn't been answered only because it is in 
a less popular sub forum. I'll try to make it short.

This websites recommends implib for the creation of import 
library therefore I have been using it. When I compile + link my 
code containing "extern( Windows )" function declarations, I get 
the following messages:
Error 42: Symbol Undefined _functionName@ordinal (generic case)
Error 42: Symbol Undefined _glGetIntegerv@8 (just an example)

Let's hypothesize that I am using "shared.dll" and I would like 
to "statically" link against it using an import library. I use 
this command: implib /noi /system shared.lib ..\shared.dll
To generate the import library. Once done, I make sure the linker 
finds it and rebuild the program. I get the same errors.

Therefore, I looked into the import library only to find that no 
exported symbols have and ordinal appended (@someInt), CONTRARILY 
to the symbols you can find in the import library provided by the 
compiler (..\D\windows\lib\*).

So... how were those generated in the first place (what makes 
them have those ordinals, was this an automated process or did 
someone actually wrote the module definition files by hand)? How 
and why is extern( Windows ) generating symbol calls expecting 
ordinals for stdcall conventions (how does it know that 
_glGetIntegerv has an ordinal of 8 for example)? Is the ordinal a 
desirable requirement for those calls?

Thanks,
Phil
January 11, 2013
Re: Creation of import libraries for Windows
On Thursday, 10 January 2013 at 17:29:13 UTC, Phil Lavoie wrote:
> Hi all,
>
> This is actually a duplicate of my post on the D.learn forums 
> :).
> I am concerned that it hasn't been answered only because it is 
> in a less popular sub forum. I'll try to make it short.
>
> This websites recommends implib for the creation of import 
> library therefore I have been using it. When I compile + link 
> my code containing "extern( Windows )" function declarations, I 
> get the following messages:
> Error 42: Symbol Undefined _functionName@ordinal (generic case)
> Error 42: Symbol Undefined _glGetIntegerv@8 (just an example)
>
> Let's hypothesize that I am using "shared.dll" and I would like 
> to "statically" link against it using an import library. I use 
> this command: implib /noi /system shared.lib ..\shared.dll
> To generate the import library. Once done, I make sure the 
> linker finds it and rebuild the program. I get the same errors.


Hello Phil Lavoie.
Yes, sometimes implib works and sometimes it doesn't.

Please check
http://blogs.msdn.com/b/oldnewthing/archive/2006/07/27/679634.aspx

"The fact that names in import libraries are decorated means that 
it is doubly crucial that you use the official import library for 
the DLL you wish to use rather than trying to manufacture one 
with an import library generation tool. As we noted earlier, the 
tool won't know whether the ordinal assigned to a named function 
was by design or merely coincidental. But what's more, the tool 
won't know what decorations to apply to the function (if the name 
was exported under an undecorated name). Consequently, your 
attempts to call the function will fail to link since the 
decorations will most likely not match up."

> Therefore, I looked into the import library only to find that 
> no exported symbols have and ordinal appended (@someInt), 
> CONTRARILY to the symbols you can find in the import library 
> provided by the compiler (..\D\windows\lib\*).

..@someInt is actually called a 'decoration'.

>
> So... how were those generated in the first place (what makes 
> them have those ordinals, was this an automated process or did 
> someone actually wrote the module definition files by hand)?

I can't give you an exact answer (I'm not from Digital Mars :)), 
but I believe they used 
http://www.digitalmars.com/ctg/coffimplib.html against the 
official .libs from the Windows SDK. Writing .def by hand is also 
an option.


> How and why is extern( Windows ) generating symbol calls 
> expecting ordinals for stdcall conventions (how does it know 
> that _glGetIntegerv has an ordinal of 8 for example)? Is the 
> ordinal a desirable requirement for those calls?
>

From
http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.71).aspx
"An underscore (_) is prefixed to the name. The name is followed 
by the at sign (@) followed by the number of bytes (in decimal) 
in the argument list. Therefore, the function declared as int 
func( int a, double b ) is decorated as follows: _func@12"

Conclusion
If you have the shared.dll only, try 'implib' or 'implib 
/system'. This may not work if the .dll contains stdcall 
functions exported as 'undecorated'.
If you have the official shared.lib, try coffimplib.
If you have both shared.dll and shared.h, you can write a module 
definition file by hand.
January 11, 2013
Re: Creation of import libraries for Windows
"Phil Lavoie" <maidenphil@hotmail.com> wrote in message 
news:cnfmacxdtgfmwmfzhfgm@forum.dlang.org...
> This websites recommends implib for the creation of import library 
> therefore I have been using it. When I compile + link my code containing 
> "extern( Windows )" function declarations, I get the following messages:
> Error 42: Symbol Undefined _functionName@ordinal (generic case)
> Error 42: Symbol Undefined _glGetIntegerv@8 (just an example)
>
> Let's hypothesize that I am using "shared.dll" and I would like to 
> "statically" link against it using an import library. I use this command: 
> implib /noi /system shared.lib ..\shared.dll
> To generate the import library. Once done, I make sure the linker finds it 
> and rebuild the program. I get the same errors.
>

The leading underscore and @NNN are part of the extern(Windows) name 
mangling, aka STDCALL.  For some dll symbols are loaded via their export 
name, which is the unmangled name of the function.  The dll's export table 
does not know anything about the mangled name, or the calling convention or 
language used.

This is where import libraries come in - they provide a mapping from the 
mangled name to the exported symbol name the dll uses, as well as 
identifying which dll the symbol can be found in.

If you generate the import library from the dll, it uses the exported name 
because that's all it knows.

There are two ways forward:
1. define a def file to use with implib that gives the correct mangled name 
for each function
2. use coffimplib to convert an existing import library to omf

This thread might also be of use: 
http://forum.dlang.org/thread/hmapfdehxvvuuxswrtyb@forum.dlang.org
January 11, 2013
Re: Creation of import libraries for Windows
Excellent!

Thanks to both of you that was very instructive and you provided 
answers to every one of my questions.

I might try to use the tools/options you suggested but I decided 
to go the "load at runtime" way instead (or rather, in the 
meantime). Since I got everything working it'd be hard to 
convince me to go back to trying to link statically but, 
nonetheless, I am still thankful for the information you provided 
and I am sure it will prove useful.

Cheers!

Phil
Top | Discussion index | About this forum | D home