“未定义的参考”在 Linux 中链接 C 代码时

发布于 2024-09-30 18:23:21 字数 464 浏览 9 评论 0原文

我有一个代码库(完全用 C 编写),通常在 Windows 下将其编译为 .DLL

我想在 Linux 下编译它,这样我就可以分发它。我不在乎将其分发为 .a.so 还是一堆 .o 文件。

所有单独的 .c 文件均已成功编译。但是,当我尝试编译包含所有 .o 文件的测试可执行文件时,我收到一堆未定义的引用错误。

所有 .o 文件都作为完整路径出现在命令行上,并且我没有收到任何有关丢失文件的错误。

cc testctd.c -o testctd.out -lm -lc $LIBRARY-PATH/*.o

我还有对 _open_write 的未定义引用> 等

I have a code library (written entirely in C) that I typically compile under Windows, into a .DLL.

I want to compile it under Linux so I can distribute it. I don't care if I distribute it as a .a, a .so, or a bunch of .o files.

All of the individual .c files compile successfully. But when I try to compile a test executable that includes all the .o files, I get a bunch of undefined reference errors.

All of the .o files are on the command line as full paths, and I don't get any errors about missing files.

cc testctd.c -o testctd.out -lm -lc $LIBRARY-PATH/*.o

I also have undefined references to _open, _write, etc.

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

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

发布评论

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

评论(2

吐个泡泡 2024-10-07 18:23:21

您将 -l 选项放在了错误的位置

-l库

-l 库

链接时搜索名为library的库。 (将库作为单独参数的第二种选择仅用于 POSIX 合规性>并且不推荐。)

在命令中写入此选项的位置会有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,

foo.o -lz bar.o

在文件 foo.o 之后但在 bar.o 之前搜索库 z。如果 bar.o 引用 z 中的函数,则可能不会加载这些函数。

链接器在标准目录列表中搜索库,该库实际上是一个名为 liblibrary.a 的文件。然后链接器使用该文件,就好像它是通过名称精确指定的一样。

You have the -l options in the wrong place

-llibrary

-l library

Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance> and is not recommended.)

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus,

foo.o -lz bar.o

searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.

云巢 2024-10-07 18:23:21

您没有提供足够的信息来获得完整的答案,但我想我知道您的一个问题:函数 openread、< code>write、close 等在 Windows 上其名称前面有下划线,但在 Linux(或任何其他 Unix 上)没有 )。当您编译 .c 文件时,编译器应该警告您这一点 - 如果没有,请打开警告!无论如何,您必须删除所有这些下划线。我会推荐一个执行如下操作的头文件:

#ifdef _WIN32
#define open(p, f, m) _open(p, f, m)
#define read(f, b, n) _read(f, b, n)
#define write(f, b, n) _write(f, b, n)
#define close(f) _close(f)
/* etc */
#endif

然后在实际代码中仅使用无下划线名称。

此外,-l 选项(例如 -lm)必须放置在所有目标文件之后。没有必要指定 -lc (并且它可能会导致问题,在这种情况下,这里无法讨论)。

You haven't given enough information for a complete answer, but I think I know one of your problems: The functions open, read, write, close, etc. have underscores in front of their names on Windows, but they do not on Linux (or any other Unix for that matter). The compiler should have warned you about that when you compiled the .c files -- if it didn't, turn on warnings! Anyway, you're going to have to remove all those underscores. I would recommend a header file that does something like the following:

#ifdef _WIN32
#define open(p, f, m) _open(p, f, m)
#define read(f, b, n) _read(f, b, n)
#define write(f, b, n) _write(f, b, n)
#define close(f) _close(f)
/* etc */
#endif

and then use only the no-underscore names in your actual code.

Also, -l options (such as -lm) must be placed after all object files. It is unnecessary to specify -lc (and it may cause problems, under circumstances which are too arcane to go into here).

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