/usr/bin/C++ 无法使用共享库编译为 gcc
/usr/bin/C++ not compile as gcc with Shared library
我尝试在共享库上工作。
详细的,我按照这个link:
http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html.
这个命令一切正常:
$ gcc -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
$ ./test
但是当我从 gcc 更改为 /usr/bin/c++ 并将命令更改为:
$ /usr/bin/c++ -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test2 main.c -lfoo
/tmp/ccpEHbNV.o: In function `main':
main.c:(.text+0x16): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
在我的 libfoo.so.
中找不到方法 foo
我也尝试了另一种方式 -rdynamic,它也适用于 gcc:
gcc -rdynamic ./libfoo.so -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
但是和/usr/bin/c++也有同样的错误。
请告诉我如何让它与 /usr/bin/c++ 一起工作。
非常感谢。
问题的出现可能是因为 C++ 的名称重整。 /usr/bin/c++ 最终变成 /usr/bin/g++。 gcc 是 C 编译器,而 g++ 是 C++ 编译器。您需要使用 g++ 编译您的库 libfoo.so,然后尝试 link。它应该有效。
正如其他人所说,这是因为 C 和 C++ 编译库之间的符号命名不同,由于 C++ 具有重载函数,因此每个符号的命名应包括符号名称中的参数类型或标识实际函数的内容或 class 方法基于其参数。
与 C++ 不同,C 没有这个问题,因为没有函数重载和它的标准 ABI。如果你想混合 C/C++ 文件,你必须用 g++ 编译所有的 C 和 C++ 代码,并在 C 代码的定义中添加 extern C 关键字
#ifdef __cplusplus
extern "C" {
#endif
// your C definitions (only function definitions) goes here
#ifdef __cplusplus
}
#endif
您使用的 gcc 和 c++ 是什么版本?
理想情况下,在 same 编译器工具链系列中应该没有错误。
事实上,我编写了代码,编译并执行了相同的示例,没有任何问题。
请注意我使用的 gcc/c++ 版本。
gcc (GCC) 6.2.1 20160830
g++ (GCC) 6.2.1 20160830
我写了一个shell脚本文件来执行命令
strace c++ -c -Wall -Werror -fpic foo.c
strace c++ -shared -o libfoo.so foo.o
strace c++ -L. -Wall -o test main.c -lfoo
并收集了编译和 linking 的 strace 输出。请看下面的link
http://pastebin.com/nJpQuCfS
希望对您有所帮助。
我尝试在共享库上工作。
详细的,我按照这个link: http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html.
这个命令一切正常:
$ gcc -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
$ ./test
但是当我从 gcc 更改为 /usr/bin/c++ 并将命令更改为:
$ /usr/bin/c++ -L/home/user/foo -Wl,-rpath=/home/user/foo -Wall -o test2 main.c -lfoo
/tmp/ccpEHbNV.o: In function `main':
main.c:(.text+0x16): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
在我的 libfoo.so.
中找不到方法 foo我也尝试了另一种方式 -rdynamic,它也适用于 gcc:
gcc -rdynamic ./libfoo.so -Wl,-rpath=/home/user/foo -Wall -o test main.c -lfoo
但是和/usr/bin/c++也有同样的错误。
请告诉我如何让它与 /usr/bin/c++ 一起工作。
非常感谢。
问题的出现可能是因为 C++ 的名称重整。 /usr/bin/c++ 最终变成 /usr/bin/g++。 gcc 是 C 编译器,而 g++ 是 C++ 编译器。您需要使用 g++ 编译您的库 libfoo.so,然后尝试 link。它应该有效。
正如其他人所说,这是因为 C 和 C++ 编译库之间的符号命名不同,由于 C++ 具有重载函数,因此每个符号的命名应包括符号名称中的参数类型或标识实际函数的内容或 class 方法基于其参数。 与 C++ 不同,C 没有这个问题,因为没有函数重载和它的标准 ABI。如果你想混合 C/C++ 文件,你必须用 g++ 编译所有的 C 和 C++ 代码,并在 C 代码的定义中添加 extern C 关键字
#ifdef __cplusplus
extern "C" {
#endif
// your C definitions (only function definitions) goes here
#ifdef __cplusplus
}
#endif
您使用的 gcc 和 c++ 是什么版本?
理想情况下,在 same 编译器工具链系列中应该没有错误。
事实上,我编写了代码,编译并执行了相同的示例,没有任何问题。
请注意我使用的 gcc/c++ 版本。
gcc (GCC) 6.2.1 20160830
g++ (GCC) 6.2.1 20160830
我写了一个shell脚本文件来执行命令
strace c++ -c -Wall -Werror -fpic foo.c
strace c++ -shared -o libfoo.so foo.o
strace c++ -L. -Wall -o test main.c -lfoo
并收集了编译和 linking 的 strace 输出。请看下面的link http://pastebin.com/nJpQuCfS
希望对您有所帮助。