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

发布于 2024-08-24 06:47:26 字数 1429 浏览 11 评论 0原文

我有一个导出的

extern "C" __declspec(dllexport) int __stdcall Foo( void );

dll 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

******************************************************************************

我从以下 def 文件开始:

LIBRARY simple.dll 
EXPORTS
  Foo

这创建了一个具有以下导出的 lib 文件:

Exports
       ordinal    name
                  _Foo

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

LIBRARY simple.dll 
EXPORTS
  Foo
  Foo@0=Foo

这会产生一个带有导出的 lib 文件

Exports
       ordinal    name
                  _Foo
                  _Foo@0

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

“无法在动态链接库 simple.dll 中找到过程入口点 Foo@0”

所以看来,即使我告诉 lib.exe Foo@0 是Foo 的别名,它仍然创建一个尝试按名称加载“Foo@0”的导入库。

当我请求“Foo@0”时,有没有办法让导入库加载“Foo”?

谢谢,

大卫

I have a dll that exports

extern "C" __declspec(dllexport) int __stdcall Foo( void );

A dump of the dll shows

******************************************************************************
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

******************************************************************************

I started with the following def file:

LIBRARY simple.dll 
EXPORTS
  Foo

This created a lib file with the following exports:

Exports
       ordinal    name
                  _Foo

When I link with this library, the msvc linker complains that it can't find _Foo@0. To correct this problem, I added an alias to the def file.

LIBRARY simple.dll 
EXPORTS
  Foo
  Foo@0=Foo

Which results in a lib file with exports

Exports
       ordinal    name
                  _Foo
                  _Foo@0

Now the project links without any problem. However, when I try to run it, I get the message

"The procedure entry point Foo@0 could not be located in the dynamic link library simple.dll"

So it appears that even though I told lib.exe that Foo@0 is an alias for Foo, it still creates an import library that tries to load "Foo@0" by name.

Is there a way to get the import library to load "Foo" when I asked for "Foo@0"?

Thanks,

David

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

妥活 2024-08-31 06:47:26

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

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

不使用别名,而是使用序数:(用你的例子):

LIBRARY simple.dll 
EXPORTS
     Foo
     Foo@0    @2 ;(from your dumpbin)

为我工作:)

You had the right idea trying to use an alias ...

"it seems LIB does not accept aliased forms (it will simply ignore the part after the equal-sign); 2) it assumes all functions in the DEF file __cdecl. The second point lies in the fact that the import library it produces will map each symbol in the DLL to an internal name with an underscore prefixed, i.e., the linker using the import library will try to resolve an undefined symbol _Function to the symbol Function in the DLL. It takes no special care of the __stdcall calling convention. With some techniques we could use LIB to produce import libraries for __stdcall functions, but the caller could only call them by ordinal, not by name. The details are left as an exercise :-)." (http://wyw.dcweb.cn/stdcall.htm)

Instead of using an alias use an ordinal: (using your example):

LIBRARY simple.dll 
EXPORTS
     Foo
     Foo@0    @2 ;(from your dumpbin)

Worked for me :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文