C++程序调用 C 函数 在 g++ 链接期间获取未定义的引用
C++ program calling C Function Getting Undefined References During g++ linking
我有一个简单的C++程序,可以调用C函数。 当我链接 2 个对象文件以创建C++可执行文件时,我收到许多"未定义的引用"错误和单个"对 svrport 的多个引用"错误。 我有以下文件 chorusmain.cpp, chorusclient.c, and chorusclient.h. chorusmain.cpp 调用 chorusclient.c 中的函数。 chorusclient.c非常大,我在2年前写了它。 我现在需要在C++应用程序中使用这些函数,并且不想重新编写C++并重新调试代码。 我将chorusclient.c重构为一组可调用的函数。 为简单起见,我将代码简化为仅包含重要组件。
合唱客户
#include <...>
#include "chorusclient.h"
int my_C_Function()
{
...
}
合唱团
#ifdef __cplusplus
extern "C" {
#endif
int my_C_Function();
#ifdef __cplusplus
}
#endif
合唱.cpp
#include <...>
#include "chorusclient.h"
int main(int argc, char *arvg[])
{
...
my_C_Function();
...
}
这是 gcc/g++ 构建和链接命令,
gcc -c -o chorusclient.o chorusclient.c -I/usr/include/json-c -
I/usr/include/openssl -I/usr/include -I. -I. -lssl -lcrypto -ljson-c
g++ -c -o chorusmain.o chorusmain.cpp -I/usr/share/qt4/mkspecs/linux-g++ -I. -
I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -
I/usr/include -I. -I. -lQtGui -lQtCore -lpthread
g++ -o ChorusMain chorusclient.o chorusmain.o
我在前 2 个 gcc/g++ 版本中没有收到任何错误。 在 g++ 链接期间,我收到以下未定义的引用错误,
debian@beaglebone:~/Projects/CloudClient$ ls
chorusclient.c chorusclient.h chorusclient.o chorusmain.cpp chorusmain.o
debian@beaglebone:~/Projects/CloudClient$ g++ -o ChorusMain chorusmain.o chorusclient.o
chorusclient.o:(.data+0x0): multiple definition of `svrport'
chorusmain.o:(.data+0x0): first defined here
chorusclient.o: In function `chorusServices':
chorusclient.c:(.text+0x408): undefined reference to `OPENSSL_init_crypto'
chorusclient.c:(.text+0x416): undefined reference to `OPENSSL_init_crypto'
chorusclient.c:(.text+0x41c): undefined reference to `OPENSSL_config'
chorusclient.o: In function `httpSend':
chorusclient.c:(.text+0x1c2c): undefined reference to `OPENSSL_init_ssl'
chorusclient.c:(.text+0x1c3a): undefined reference to `OPENSSL_init_ssl'
chorusclient.c:(.text+0x1c4c): undefined reference to `OPENSSL_init_ssl'
chorusclient.c:(.text+0x1c50): undefined reference to `TLSv1_2_client_method'
chorusclient.c:(.text+0x1c58): undefined reference to `SSL_CTX_new'
chorusclient.c:(.text+0x1c62): undefined reference to `SSL_CTX_set_options'
chorusclient.c:(.text+0x1c7e): undefined reference to `ERR_print_errors_fp'
chorusclient.c:(.text+0x1ca0): undefined reference to `SSL_new'
chorusclient.c:(.text+0x1caa): undefined reference to `SSL_set_fd'
chorusclient.c:(.text+0x1cb0): undefined reference to `SSL_connect'
chorusclient.c:(.text+0x1ce4): undefined reference to `SSL_get_peer_certificate'
chorusclient.c:(.text+0x1cec): undefined reference to `X509_get_subject_name'
chorusclient.c:(.text+0x1cfa): undefined reference to `X509_NAME_oneline'
chorusclient.c:(.text+0x1d1a): undefined reference to `X509_get_issuer_name'
chorusclient.c:(.text+0x1d28): undefined reference to `X509_NAME_oneline'
chorusclient.c:(.text+0x1d3e): undefined reference to `X509_free'
chorusclient.c:(.text+0x1d4a): undefined reference to `SSL_get_current_cipher'
chorusclient.c:(.text+0x1d52): undefined reference to `SSL_CIPHER_get_name'
chorusclient.c:(.text+0x1d80): undefined reference to `SSL_write'
chorusclient.c:(.text+0x1d90): undefined reference to `SSL_read'
chorusclient.c:(.text+0x1df2): undefined reference to `SSL_read'
chorusclient.c:(.text+0x1e8e): undefined reference to `SSL_free'
chorusclient.c:(.text+0x1e9a): undefined reference to `SSL_CTX_free'
chorusclient.o: In function `jsonBatteryData':
chorusclient.c:(.text+0x21a8): undefined reference to `json_object_new_object'
chorusclient.c:(.text+0x21b2): undefined reference to `json_object_new_string'
chorusclient.c:(.text+0x21be): undefined reference to `json_object_new_string'
chorusclient.c:(.text+0x21ca): undefined reference to `json_object_new_string'
chorusclient.c:(.text+0x21d8): undefined reference to `json_object_new_double'
chorusclient.c:(.text+0x21e6): undefined reference to `json_object_new_double'
chorusclient.c:(.text+0x21f4): undefined reference to `json_object_new_double'
chorusclient.c:(.text+0x2202): undefined reference to `json_object_new_double'
chorusclient.c:(.text+0x2210): undefined reference to `json_object_new_double'
chorusclient.c:(.text+0x2220): undefined reference to `json_object_object_add'
chorusclient.c:(.text+0x222e): undefined reference to `json_object_object_add'
chorusclient.c:(.text+0x223c): undefined reference to `json_object_object_add'
chorusclient.c:(.text+0x224a): undefined reference to `json_object_object_add'
chorusclient.c:(.text+0x2258): undefined reference to `json_object_object_add'
chorusclient.o:chorusclient.c:(.text+0x2266): more undefined references to `json_object_object_add' follow
chorusclient.o: In function `jsonBatteryData':
chorusclient.c:(.text+0x2292): undefined reference to `json_object_to_json_string'
chorusclient.o: In function `blockencrypt':
chorusclient.c:(.text+0x22de): undefined reference to `EVP_CIPHER_CTX_new'
chorusclient.c:(.text+0x22ee): undefined reference to `EVP_aes_256_cbc'
chorusclient.c:(.text+0x22fe): undefined reference to `EVP_EncryptInit_ex'
chorusclient.c:(.text+0x231a): undefined reference to `EVP_EncryptUpdate'
chorusclient.c:(.text+0x233c): undefined reference to `EVP_EncryptFinal_ex'
chorusclient.c:(.text+0x2354): undefined reference to `EVP_CIPHER_CTX_free'
chorusclient.o: In function `decrypt':
chorusclient.c:(.text+0x2370): undefined reference to `EVP_CIPHER_CTX_new'
chorusclient.c:(.text+0x2380): undefined reference to `EVP_aes_256_cbc'
chorusclient.c:(.text+0x2390): undefined reference to `EVP_DecryptInit_ex'
chorusclient.c:(.text+0x23ac): undefined reference to `EVP_DecryptUpdate'
chorusclient.c:(.text+0x23ce): undefined reference to `EVP_DecryptFinal_ex'
chorusclient.c:(.text+0x23e6): undefined reference to `EVP_CIPHER_CTX_free'
chorusclient.o: In function `handleErrors':
chorusclient.c:(.text+0x2404): undefined reference to `ERR_print_errors_fp'
collect2: error: ld returned 1 exit status
debian@beaglebone:~/Projects/CloudClient$
当我创建一个调用 chorusclient.c 的简单 C 程序并构建一个链接时,我没有收到未定义的引用错误,并且程序可以正常工作。 有什么想法吗?
你说你有:
gcc -c -o chorusclient.o chorusclient.c -I/usr/include/json-c
-I/usr/include/openssl -I/usr/include -I. -I. -lssl -lcrypto -ljson-c
g++ -c -o chorusmain.o chorusmain.cpp -I/usr/share/qt4/mkspecs/linux-g++ -I.
-I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4
-I/usr/include -I. -I. -lQtGui -lQtCore -lpthread
g++ -o ChorusMain chorusclient.o chorusmain.o
编译以创建目标文件时列出库;尝试链接可执行文件时不列出库。 这些库在创建对象文件时无关紧要 — 它们在链接可执行文件时至关重要。
因此,您需要更多类似的东西:
gcc -Wall -Werror -c -o chorusclient.o chorusclient.c -I/usr/include/json-c
-I/usr/include/openssl -I/usr/include -I.
g++ -Wall -Werror -c -o chorusmain.o chorusmain.cpp -I/usr/share/qt4/mkspecs/linux-g++
-I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4
-I/usr/include -I.
g++ -o ChorusMain chorusclient.o chorusmain.o -lQtGui -lQtCore -lpthread -lssl -lcrypto -ljson-c
我不相信你需要-I/usr/include
,而且你通常不需要-I.
(除非你坚持使用#include <chorusclient.h>
而不是#include "chorusclient.h"
),而且你绝对不需要重复-I.
。
您可能需要对链接中的库列表重新排序 - 最好-lpthread
放在末尾。
我添加了-Wall -Werror
选项,因为除非它至少在这些选项下干净地编译,否则您不应该尝试运行代码(我会在我的代码中添加更多内容 - 这足以说明这一点)。
我有点惊讶你需要-I/usr/include/openssl
行;你应该使用#include <openssl/ssl.h>
等(用于OpenSSL标头)这样你就不需要-I/usr/include/openssl
命令行选项吗? 同样,也许,使用Qt和JSON-C标头?
另一个问题是你有一个对象 - 可能是一个全局变量 - 称为svrport
在chorusclient.o
和chorusmain.o
中定义。 这意味着通过某种机制,您可以在两个源文件中定义(而不是声明)相同的对象。 这可能是因为它是在标头中定义而不是声明的(但代码中未显示)。 或者可能是因为您在两个源文件中都定义了它。 如果它需要是一个全局变量,它应该在标头中声明并在其中一个源文件中定义(可能是chorusclient.c
,因为chorusclient.h
标头声明它),而不是在另一个源文件中定义。
- 获取对function_name的未定义引用
- 为不应该获得未定义行为的内容获取未定义的行为
- Armadillo正在为共享的lapack库获取未定义的参考
- 获取未定义的符号:尝试使用Clang地址清理器时__asan_memset
- 获取作为类变量的 Deque 大小时未定义的行为
- 获取线函数未定义错误。无法在字符串中保存可验证的内容
- 获取未初始化对象成员的地址是否定义良好?
- C++程序调用 C 函数 在 g++ 链接期间获取未定义的引用
- 尝试编写进程内存并获取用户定义的文字运算符未找到
- 获取错误:未定义对函数 Android NDK 的引用
- 获取数组/向量末尾地址的未定义行为
- 在 C++ 年的 iostream 中未定义的获取线
- wxWidget获取许多未定义的引用
- 在给定的代码中获取错误(标识符未定义)
- 获取函数运算符<未定义的引用
- 错误:标识符类名未定义?为我在文件中创建的所有类获取此内容
- C++ 获取未定义的符号错误
- 正在尝试将C++绑定到Haskell:获取未定义的引用错误
- 获取未定义的引用错误
- 静态结构成员获取"未定义的引用"。不知道为什么