从使用stdcall的DLL创建MSVC导入库

Dav*_*vid 6 import dll stdcall visual-c++

我有一个出口的DLL

extern "C" __declspec(dllexport) int __stdcall Foo( void );
Run Code Online (Sandbox Code Playgroud)

dll的转储显示

******************************************************************************
Section:             Exports
File Offset:         00001400 (5120)
  Flags:             00000000
  Time Stamp:        00000000
  Major Version:     0000
  Minor Version:     0000

Exports from simple.dll
  3 exported name(s), 3 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    -------- ---- ---- ----
    00002104    3 0000 std::nothrow
    00001258    2 0001 Foo
    000020F8    1 0002 ___CPPdebugHook

******************************************************************************
Run Code Online (Sandbox Code Playgroud)

我从以下def文件开始:

LIBRARY simple.dll 
EXPORTS
  Foo
Run Code Online (Sandbox Code Playgroud)

这创建了一个包含以下导出的lib文件:

Exports
       ordinal    name
                  _Foo
Run Code Online (Sandbox Code Playgroud)

当我链接到这个库时,msvc链接器抱怨它找不到_Foo @ 0.为了解决这个问题,我在def文件中添加了一个别名.

LIBRARY simple.dll 
EXPORTS
  Foo
  Foo@0=Foo
Run Code Online (Sandbox Code Playgroud)

这导致带有导出的lib文件

Exports
       ordinal    name
                  _Foo
                  _Foo@0
Run Code Online (Sandbox Code Playgroud)

现在项目链接没有任何问题.但是,当我尝试运行它时,我收到了消息

"程序入口点Foo @ 0无法位于动态链接库simple.dll中"

因此,即使我告诉lib.exe Foo @ 0是Foo的别名,它仍会创建一个导入库,尝试按名称加载"Foo @ 0".

当我要求"Foo @ 0"时,有没有办法让导入库加载"Foo"?

谢谢,

大卫

Jam*_*mes 5

您尝试使用别名的想法正确...

“ LIB似乎不接受别名形式(它只会忽略等号后的部分); 2)它假定DEF文件__cdecl中的所有函数。第二点在于,它产生的导入库将映射DLL中的每个符号都带有一个带下划线前缀的内部名称,即,使用导入库的链接程序将尝试将未定义的符号_Function解析为DLL中的符号Function,而无需特别注意__stdcall调用约定。我们可以使用LIB为__stdcall函数生成导入库的一些技术,但是调用者只能按序调用它们,而不能按名称调用。详细信息留作练习:-)。” (http://wyw.dcweb.cn/stdcall.htm

代替使用别名,使用ordinal :(使用您的示例):

LIBRARY simple.dll 
EXPORTS
     Foo
     Foo@0    @2 ;(from your dumpbin)
Run Code Online (Sandbox Code Playgroud)

为我工作:)

  • 奇迹般有效!正是我所需要的。令人惊讶的是,Microsoft使创建导入库变得如此困难。谢谢!! (2认同)