带下划线的未解析引用

发布于 2024-07-13 23:42:54 字数 275 浏览 6 评论 0原文

我在 VS2008 中有一个 x64 项目,需要包含一个多年前用 Fortran 编写的旧遗留库。 我没有源码,无法重新编译。 .lib 中的函数名称前面带有下划线,但 x64 项目仅使用 fastcall 引用,它不想识别 stdcall 或 cdecl 引用。 有什么可以告诉构建识别带有下划线的名称吗?

编辑

所有有争议的点,因为一旦我解决了命名问题,它最终告诉我致命错误 LNK1112 :模块机器类型 x86 与目标机器类型 x64 冲突,所以我无论如何都无法链接这个旧库。

I have an x64 project in VS2008 that needs to include an old legacy library written in Fortran years ago. I do not have the source and cannot recompile it. The function names in the .lib are prepended with an underscore, but the x64 projects only use fastcall reference which does not want to recognize stdcall or cdecl references. Is there anything that will tell the build to recognize the names with prepended underscores?

EDIT

All moot points since once I got past the naming problem it ended up telling me fatal error LNK1112 : module machine type x86 conflicts with target machine type x64, so i can't link this old library in anyway.

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

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

发布评论

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

评论(5

习惯成性 2024-07-20 23:42:54

带有前缀下划线的名称由 C 链接使用,因此如果您的实现语言是 C++(是吗?),您应该使用此声明

extern "C" {
  int foo();
  float bar();
}

它也应该使用 __cdecl,尽管我对此不确定。

Names with prepended underscores are used by C linkage, so if your implementation language is C++ (is it?), you should use this declaration

extern "C" {
  int foo();
  float bar();
}

It should also use __cdecl, although I'm not sure about that.

安静 2024-07-20 23:42:54

我假设您的旧库是 32 位的。 您是否尝试过将项目编译为 x86 而不是 x64,看看问题是否来自 x64 编译? 如果是这种情况,您可以尝试这里的内容:

从 64 位进程调用 32 位代码

I'm assuming that your legacy library is 32 bit. Have you tried compiling your project as x86 instead of x64 to see if the problem is from the x64 compile? If that's the case, you could try the stuff here:

Calling 32bit Code from 64bit Process

别再吹冷风 2024-07-20 23:42:54

你肯定需要头文件。
如果问题仍然存在,则意味着标头中的定义未指定调用约定。

处理链接错误的一般方法:

  1. 转储应用程序使用的函数

    dumpbin /symbols

  2. 转储库和 dll

    转储箱/导出
    dumpbin /exports

对于静态库

dumpbin /symbols <libraryFileName.lib>
  1. 在 2 个转储中查找函数名称(3 个为 dll+导入库)
    并确保它们相同。

  2. 您发现的任何不匹配都将表明您的问题是什么

  3. 更改您的调用以最终得到与导出的内容相同的结果


解释(部分)结果:

C函数:(

_functionName = C function, __cdecl calling convention
_functionName@12 = C function, __stdcall calling convention
@functionName@12 = C function, __fastcall calling convention

当然,数字不必是12)

C++函数

它们看起来像?functionName@
这就是装饰的名字。
但转储中还包含未装饰的。

示例:

?functionName@@$J0YMHHPADPAUKeyVal@@@Z
(extern "C" int __clrcall functionName(int,char *,struct KeyVal *))
=> you have all the info, including the fact that this is compiled to
managed code (__clrcall)

?functionName@@YAHHPADPAUKeyVal@@@Z
(int __cdecl functionName(int,char *,struct KeyVal *))
=> normal C++ function

?functionName@className@@QAEHHPADPAUKeyVal@@@Z
(public: int __thiscall className::functionName(int,char *,struct KeyVal
*))
=> member function (because of __thiscall) of the class className

等等。


提示:我建议转储到文件中,因为生成的转储可能很大
dumpbin /导出 fileToDump.lib > dumpResult.txt

额外提示:有时在一次转储中您会看到 unsigned short 和
在另一个 wchar_t 中
这意味着编译不是使用相同的设置完成的
对于 wchar_t (是否为原生类型)

You definitely need the header file.
If you still have the problem, it means the definitions in the header don't specify the calling convention.

The general approach to handle linke errors:

  1. Dump the functions used by your application

    dumpbin /symbols

  2. Dump the library and and the dll

    dumpbin /exports
    dumpbin /exports

For static libraries

dumpbin /symbols <libraryFileName.lib>
  1. Find the function names in the 2 dumps (3 for the dll+import library)
    and make sure they are identical.

  2. Any mismatch you find will indicate what your problem is

  3. Change your call to end up with the same result as the exported stuff


Interpreting (some of) the results:

C functions:

_functionName = C function, __cdecl calling convention
_functionName@12 = C function, __stdcall calling convention
@functionName@12 = C function, __fastcall calling convention

(of course, the number does not have to be 12)

C++ functions

They look like ?functionName@
That is the decorated name.
But the dump also contains the undecorated one.

Examples:

?functionName@@$J0YMHHPADPAUKeyVal@@@Z
(extern "C" int __clrcall functionName(int,char *,struct KeyVal *))
=> you have all the info, including the fact that this is compiled to
managed code (__clrcall)

?functionName@@YAHHPADPAUKeyVal@@@Z
(int __cdecl functionName(int,char *,struct KeyVal *))
=> normal C++ function

?functionName@className@@QAEHHPADPAUKeyVal@@@Z
(public: int __thiscall className::functionName(int,char *,struct KeyVal
*))
=> member function (because of __thiscall) of the class className

And so on.


Tip: I recomand dump into a file because the resulting dumps can be big
dumpbin /exports fileToDump.lib > dumpResult.txt

Bonus tip: sometimes in one dump you will see unsigned short and
in another wchar_t
This means the compilation was not done with the same settings
for wchar_t (native type or not)

柏拉图鍀咏恒 2024-07-20 23:42:54

您的 x64 项目使用什么语言? 您应该能够在函数的外部定义中指定调用约定:

  extern int __stdcall foo();

What language is your x64 project in? You should be able to specify the calling convention in your extern definition for the function:

  extern int __stdcall foo();
黑寡妇 2024-07-20 23:42:54

您多年前就提到过 Fortran,很可能它是 32 位的。 名称修改(前导下划线)只是冰山一角,即使您设法解决此问题(调用约定问题),您仍然会遇到从 32 位调用 64 位的问题。 本·罗宾斯(Ben Robbins)上面的链接可能会有所帮助。 我们遇到了类似的问题,我们认为也许我们能够将 32 位 DLL 包装在 COM 包装器中,然后从 64 位调用 COM 包装器。 不知道这是否可行,因为我们最终找到了源代码并获得了良好的 64 位编译。

You mentioned Fortran from years ago, chances are very good it's 32-bit. The name-mangling (leading underscore) is the tip of the iceberge, even if you managed to fix this (calling convention issue), you'd still have the problem of calling 64-bit from 32-bit. The link by Ben Robbins above may help. We had a similar issue, we considered that perhaps we'd be able to wrap our 32-bit DLLs in COM wrappers and then call the COM wrappers from 64-bit. Don't know if that would work, as we ended up finding the source code and getting a good 64-bit compile.

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