窗户上的strnicmp在哪里?
我正在尝试在不寻常的上下文中在Windows上编译Python,并遇到这个问题:
a.o : error LNK2019: unresolved external symbol strnicmp referenced in function connection_clear
好的,所以我没有在包含strnicmp
的适当库中链接,那是哪一个?找不到它,所以我写了一个脚本来搜索我整个硬盘上的每个.lib
文件,在所有硬盘上运行dumpbin/enforts
结果。
结果是,就此过程所示, no 库中包含strnicmp
。
更多的搜索导致我到 https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnicmp-wcsnicmp?view=msvc-170
Microsoft特定功能名称strnicmp和wcsnicmp是_strnicmp和_wcsnicmp functions的弃用别名。
从表面上看,这似乎是解释的开始。链接器,我和我的搜索脚本都无法找到strnicmp
,因为在对象代码级别上,它不存在。它可能只是某些标头文件中的#define
,尽管这提出了为什么它在包含connection_clear
的源文件上不起作用的问题。
只是为了确保我写了一个测试程序。
(c1) R:\>type call-strnicmp.c
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
if (argc == 2 && !strnicmp(argv[1], "foo", 3)) puts("you said foo");
else
puts("you did not say foo");
return 0;
}
(c1) R:\>cl call-strnicmp.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.31.31104 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
call-strnicmp.c
Microsoft (R) Incremental Linker Version 14.31.31104.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:call-strnicmp.exe
call-strnicmp.obj
(c1) R:\>call-strnicmp.exe foo
you said foo
好的,因此strnicmp
被正确调用,大概是通过上述标头调用。只是为了确定:
(c1) R:\>dumpbin /symbols call-strnicmp.obj
Microsoft (R) COFF/PE Dumper Version 14.31.31104.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file call-strnicmp.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 01047980 ABS notype Static | @comp.id
001 80010190 ABS notype Static | @feat.00
002 00000002 ABS notype Static | @vol.md
003 00000000 SECT1 notype Static | .drectve
Section length 2F, #relocs 0, #linenums 0, checksum 0
005 00000000 SECT2 notype Static | .debug$S
Section length 68, #relocs 0, #linenums 0, checksum 0
007 00000000 SECT3 notype Static | .text$mn
Section length 5D, #relocs 6, #linenums 0, checksum D202F0CD
009 00000000 UNDEF notype () External | puts
00A 00000000 UNDEF notype () External | strnicmp
00B 00000000 SECT3 notype () External | main
00C 00000000 SECT3 notype Label | $LN5
00D 00000000 SECT4 notype Static | .xdata
Section length 8, #relocs 0, #linenums 0, checksum E7553388
00F 00000000 SECT4 notype Static | $unwind$main
010 00000000 SECT5 notype Static | .pdata
Section length C, #relocs 3, #linenums 0, checksum CE23E617
012 00000000 SECT5 notype Static | $pdata$main
013 00000000 SECT6 notype Static | .data
Section length 2C, #relocs 0, #linenums 0, checksum C7B9A925
015 00000000 SECT6 notype Static | $SG10717
016 00000008 SECT6 notype Static | $SG10718
017 00000018 SECT6 notype Static | $SG10719
018 00000000 SECT7 notype Static | .chks64
Section length 38, #relocs 0, #linenums 0, checksum 0
String Table Size = 0x1D bytes
Summary
38 .chks64
2C .data
68 .debug$S
2F .drectve
C .pdata
5D .text$mn
8 .xdata
... er? strnicmp
正在导入,但不是,Microsoft文档建议的预先列出。引用是指未经修饰的名称。
那是怎么回事?大概我在这里误解了链条中的某些东西。有没有办法导出函数,以使其不会在任何库的dumpbin /enfort < /code>输出中显示?
I'm trying to compile Python on Windows in an unusual context, and running into this problem:
a.o : error LNK2019: unresolved external symbol strnicmp referenced in function connection_clear
Okay, so I'm not linking in the proper library containing strnicmp
, which one is that? Couldn't find it, so I wrote a script to search through every .lib
file on my entire hard disk, run dumpbin /exports
on all of them, and collect the results.
And the result was that as far as this process could tell, there is no library containing strnicmp
.
A bit more searching led me to https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnicmp-wcsnicmp?view=msvc-170
The Microsoft-specific function names strnicmp and wcsnicmp are deprecated aliases for the _strnicmp and _wcsnicmp functions.
On the face of it, that would seem to be the beginning of an explanation. Neither the linker nor I nor my search script can find strnicmp
because at the object code level, it doesn't exist; it's probably just a #define
in some header file, though that raises the question of why this was not working on the source file containing connection_clear
.
Just to make sure, I wrote a test program.
(c1) R:\>type call-strnicmp.c
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
if (argc == 2 && !strnicmp(argv[1], "foo", 3)) puts("you said foo");
else
puts("you did not say foo");
return 0;
}
(c1) R:\>cl call-strnicmp.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.31.31104 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
call-strnicmp.c
Microsoft (R) Incremental Linker Version 14.31.31104.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:call-strnicmp.exe
call-strnicmp.obj
(c1) R:\>call-strnicmp.exe foo
you said foo
Okay, so strnicmp
is being called correctly, presumably via the aforementioned header. Just to make doubly sure:
(c1) R:\>dumpbin /symbols call-strnicmp.obj
Microsoft (R) COFF/PE Dumper Version 14.31.31104.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file call-strnicmp.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 01047980 ABS notype Static | @comp.id
001 80010190 ABS notype Static | @feat.00
002 00000002 ABS notype Static | @vol.md
003 00000000 SECT1 notype Static | .drectve
Section length 2F, #relocs 0, #linenums 0, checksum 0
005 00000000 SECT2 notype Static | .debug$S
Section length 68, #relocs 0, #linenums 0, checksum 0
007 00000000 SECT3 notype Static | .text$mn
Section length 5D, #relocs 6, #linenums 0, checksum D202F0CD
009 00000000 UNDEF notype () External | puts
00A 00000000 UNDEF notype () External | strnicmp
00B 00000000 SECT3 notype () External | main
00C 00000000 SECT3 notype Label | $LN5
00D 00000000 SECT4 notype Static | .xdata
Section length 8, #relocs 0, #linenums 0, checksum E7553388
00F 00000000 SECT4 notype Static | $unwind$main
010 00000000 SECT5 notype Static | .pdata
Section length C, #relocs 3, #linenums 0, checksum CE23E617
012 00000000 SECT5 notype Static | $pdata$main
013 00000000 SECT6 notype Static | .data
Section length 2C, #relocs 0, #linenums 0, checksum C7B9A925
015 00000000 SECT6 notype Static | $SG10717
016 00000008 SECT6 notype Static | $SG10718
017 00000018 SECT6 notype Static | $SG10719
018 00000000 SECT7 notype Static | .chks64
Section length 38, #relocs 0, #linenums 0, checksum 0
String Table Size = 0x1D bytes
Summary
38 .chks64
2C .data
68 .debug$S
2F .drectve
C .pdata
5D .text$mn
8 .xdata
... er? strnicmp
is being imported, but not with the prepended underscore suggested by the Microsoft documentation. The reference is to the unadorned name.
So what's going on? Presumably I am misunderstanding something in the chain here. Is there a way for a function to be exported such that it does not show up in the dumpbin /exports
output of any library?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
_strnicmp
函数是 Microsoft Visual C Extension 在Microsoft C运行时发现。ucrt.lib
或libucrt.lib
。较早的 strnicmp 是不弃用的别名。 (更新:根据您告诉我的内容,它实际上被定义为OldNames.lib
中的弱符号。我最初是基于MSDN文章认为是< 了。代码> vcruntime.lib ,但我误会 通过使用此处列出的编译器标志来编译,或链接到库的正确版本,运行时间/crt/crt-library-features?view = msvc-170“ rel =“ nofollow noreferrer”>。对于动态链接,这是
/md
。还可以指定包含链接器选项(例如ucrt.lib
或libucrt.lib
)的库。但是,在使用
dumpbin/imports
的测试中,一个简单的测试程序:使用
/md
编译时,将外部符号strnicmp
作为别名解决。到_strnicmp
inapi-ms-win-crt-string-l1-1-0.dll
并调用了。因此,请确保从MSVC命令提示符中使用正确的标头文件来编译源。您还可以使用Cl
环境变量设置Cl.exe
编译器标志。The
_strnicmp
function is a Microsoft Visual C extension that is found in the Microsoft C runtime.ucrt.lib
orlibucrt.lib
. The olderstrnicmp
is a deprecated alias for it. (Update: Based on what you told me, it’s actually defined as a weak symbol inoldnames.lib
. I originally thought, based on a MSDN article, that it wasvcruntime.lib
, but I was mistaken.)You will normally want to link a program that needs it by compiling with the compiler flags listed here, or linking to the correct version of the libraries. For dynamic linkage, this is
/MD
. It is also possible to specify which libraries to include (e.g.ucrt.lib
orlibucrt.lib
) with linker options.In a test with
DUMPBIN /IMPORTS
, however, a simple test program:when compiled with
/MD
, resolved the external symbolstrnicmp
as an alias to_strnicmp
inapi-ms-win-crt-string-l1-1-0.dll
and called that. Therefore, make sure you are compiling your source with the correct header files, from the MSVC command prompt. You may also setCL.EXE
compiler flags with theCL
environment variable.它在
oldnames.lib
中。它没有在列表中显示,因为事实证明,对于静态库,您需要使用dumpbin/符号
而不是/exports
输出。It's in
oldnames.lib
. It didn't show up in the listing because it turns out that for a static library, you need to usedumpbin /symbols
instead of/exports
, otherwise it silently gives no output.