我正在 Linux 上移植一个 WIN32 库。我能够毫无错误地编译我的库。但是当我尝试链接时,它会出现以下链接错误
未定义对“setmode”的引用
我知道setmode函数是标准库函数,它位于unistd.h中,我在通过终端链接时提供参数-lc 。
这是更多关于setmode的链接。
有什么帮助吗?
恐怕这些答案都是无稽之谈。来自 Win32 环境的程序正在使用两个可能的函数之一:要么是MSDN 中记录setmode
的 Microsoft_setmode
函数,要么是 Cygwin 对它的模仿,称为.setmode
这与 BSD 无关setmode
。这是一个有两个参数的函数,它将文件描述符设置为二进制或文本翻译模式。
如果您的程序需要此功能,但您链接到 LibBSD,程序可能会链接,但它是不正确的。
GNU C 库不提供用于操作FILE *
流或描述符的文本或二进制模式的接口,如果提供,它不会做任何事情,因为这两种模式是相同的。
在 Cygwin 上需要 Cygwinsetmode
函数的代码可能会在 Unix 上不做任何事情而侥幸逃脱:也就是说:
#ifdef __CYGWIN__
setmode(fileno(my_stdio_stream), O_BINARY);
#elif _WIN32
_setmode(_fileno(my_stdio_stream), _O_BINARY);
#else
/* nothing on systems with no text-vs-binary mode */
#endif
我也遇到了这个问题。链接发生在制作过程中,因此会发生这种情况,并且与 c 没有业务往来的人(如我)尝试使用 cygwin 或 mingw。感谢 Cairnarvon 的回答,我了解到缺少必要的包含语句:
#include <io.h>
...在调用该setmode
函数的模块中(在我的情况下,我正在尝试在 Cygwin 64 位上构建 GDAL)。错误仍然存在,直到我看到这些人的回答并了解到 64 位版本的 Cygwin 没有预先强调 32 位版本的方式。因此,我手动进行了前置操作,并且成功完成了 [更多]。我希望这有帮助。
setmode
不是标准库函数;这是一个 libbsd 函数。这只是在 OS X 等 BSD 派生系统上的相同内容,该手册页来自该系统。传递-lbsd
参数以让链接器在 Linux 上找到它。
始终信任您自己系统的手册页而不是 Internet 的手册页。
您必须使用<bsd/unistd.h>
标题(不是<unistd.h>
)。
在我的 Ubuntu 机器上,我必须安装软件包libbsd0
并且libbsd-dev
:
sudo apt-get install libbsd0 libbsd-dev
之后,我能够编译以下程序:
#include <bsd/unistd.h>
int main(void) {
setmode(0);
return 0;
}
使用命令:
gcc hello.c -lbsd