未定义的引用(但 nm 表示该函数存在)[重复]
Posted
技术标签:
【中文标题】未定义的引用(但 nm 表示该函数存在)[重复]【英文标题】:Undefined reference (but nm says the function exists) [duplicate] 【发布时间】:2017-07-12 09:42:17 【问题描述】:我有一个相机制造商提供的库,在提供的演示代码中,一个名为 metadata_init() 的函数工作正常,但在我的代码中,我得到一个未定义的引用错误。
演示代码的 make 输出:
/opt/linaro-multilib-2013.09-gcc4.8/bin/arm-linux-gnueabihf-gcc -lm -g -L"/home/aro/Downloads" -o hicore demoS2.c -lpthread -lyuvlib -lrt
就是这样,构建成功了,我将有一个工作的 ./hicore 应用程序。
我的项目稍微复杂一点,我用eclipse编译。 控制台输出为:
11:33:23 **** Build of configuration Camera-R4-Debug for project Camera ****
make all
Building file: ../src/Camera.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Camera.d" -MT"src/Camera.o" -o "src/Camera.o" "../src/Camera.cpp"
../src/Camera.cpp: In function ‘int metadata_construct_http_message(char*, METADATA_HTTP_MESSAGE_TYPE, void*, int*)’:
../src/Camera.cpp:379:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
"</svg>\r\n";
^
../src/Camera.cpp: In function ‘int main()’:
../src/Camera.cpp:426:97: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
(void)metadata_init("stream.cgi", strlen("stream.cgi"), metadata_construct_http_message);
^
Finished building: ../src/Camera.cpp
Building file: ../src/CameraFrameGrabber.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraFrameGrabber.d" -MT"src/CameraFrameGrabber.o" -o "src/CameraFrameGrabber.o" "../src/CameraFrameGrabber.cpp"
Finished building: ../src/CameraFrameGrabber.cpp
Building file: ../src/CameraLogger.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/home/aro/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraLogger.d" -MT"src/CameraLogger.o" -o "src/CameraLogger.o" "../src/CameraLogger.cpp"
Finished building: ../src/CameraLogger.cpp
Building file: ../src/CameraParameter.cpp
Invoking: Cross G++ Compiler
arm-linux-gnueabihf-g++ -I/opt/Camerasdk/R4/include -I"/home/aro/cameraBuilds/Wrapper/include" -I"/opt/ExternalLibraries/curl/Camera/R4/include" -I"/opt/ExternalLibraries/libxml2/Camera/R4/include" -I"/opt/ExternalLibraries/OpenCV24/Camera/R4/include" -I"/home/aro/cameraBuilds/Camera" -I/opt/InternalLibraries/include -I/opt/InternalLibraries/include_linux -I/opt/InternalLibraries/ipslib/include -I/opt/InternalLibraries/ipsstream/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/CameraParameter.d" -MT"src/CameraParameter.o" -o "src/CameraParameter.o" "../src/CameraParameter.cpp"
Finished building: ../src/CameraParameter.cpp
Building target: Camera
Invoking: Cross G++ Linker
arm-linux-gnueabihf-g++ -L/opt/Camerasdk/R4/lib -L"/cameraBuilds/Wrapper/Camera-R4-Debug" -L"/opt/ExternalLibraries/curl/Camera/R4/lib" -L"/opt/ExternalLibraries/libxml2/Camera/R4/lib" -L"/opt/ExternalLibraries/OpenCV24/Camera/R4/lib" -L"/opt/DetectionModules/Camera/R4/lib" -L/home/aro/Downloads -o "Camera" ./src/Camera.o ./src/CameraFrameGrabber.o ./src/CameraLogger.o ./src/CameraParameter.o -lWrapper -lxml2 -lopencv_highgui -lopencv_imgproc -lopencv_core -lpthread -lyuvlib -lrt -llibjasper -llibjpeg -llibpng -llibtiff -lzlib -lcurl
./src/Camera.o: In function `main':
/home/aro/cameraBuilds/Camera/Camera-R4-Debug/../src/Camera.cpp:426: undefined reference to `metadata_init(char*, int, int (*)(char*, METADATA_HTTP_MESSAGE_TYPE, void*, int*))'
collect2: error: ld returned 1 exit status
make: *** [Camera] Error 1
11:33:24 Build Finished (took 1s.212ms)
代码本身是一样的,我只是复制过来的。
元数据.h:
#ifndef _HIK_METADATA_H_
#define _HIK_METADATA_H_
const int max_http_body_len = 100 * 1024;
typedef enum
CMD_ADD_TYPE = 1,
CMD_OTHER,
METADATA_CTRL_TYPE;
typedef struct
int length;
int fd;
METADATA_CTRL_TYPE cmd_type;
METADATA_HEADER;
typedef struct
char option[128];
int share_socket;
METADATA_ADD_CFG;
typedef enum
HTTP_HEADER_TYPE = 1,
HTTP_BODY_TYPE,
METADATA_HTTP_MESSAGE_TYPE;
typedef struct
char boundary[64];
char http_content_type[64];
char multipart_content_type[64];
METADATA_MULTIPART_TYPE;
typedef int (*p_metadata_construct_http_msg_callback_f)(char *p_option, METADATA_HTTP_MESSAGE_TYPE cmd_type, void *p_data, int *p_data_len);
int metadata_init(char *p_metadata_url, int url_len, p_metadata_construct_http_msg_callback_f p_callback_f);
#endif
在 Camera.cpp 中:
#include "Metadata.h"
int metadata_construct_http_message(char *p_option, METADATA_HTTP_MESSAGE_TYPE cmd_type, void *p_data, int *p_data_len)
// Removed for SO
return 0;
int main()
(void)metadata_init("stream.cgi", strlen("stream.cgi"), metadata_construct_http_message);
...
是什么原因造成的,我该如何调试这个问题来缩小解决方法的范围?
【问题讨论】:
在哪里定义了metadata_init
?它的实现在哪里?
另外,我强烈建议您仔细查看这些警告。他们在那里是有原因的。
在相机厂商提供的libyuvlib.a中。我可以用 nm 找到它,它在那里列出,但我无法让它在我的项目中工作。
是的,警告都在新的演示代码中。一旦代码运行,我将删除它们。
【参考方案1】:
它认为问题可能在于metadata_init
是一个 C 函数,但您在 C++ 代码中使用它。
在这种情况下,必须在头文件中使用extern "C"
,如下所示:
#ifdef __cplusplus
extern "C"
#endif
// embed the whole contents of the header file here, I just put the function here for brevity
int metadata_init(char *p_metadata_url, int url_len, p_metadata_construct_http_msg_callback_f p_callback_f);
#ifdef __cplusplus
#endif
这是因为名称修改规则。在 C 和 C++ 中,名称的处理方式不同。使用extern "C"
,您告诉编译器内部的名称应该与“C”修饰一起使用。
与 C 相比,C++ 必须进行复杂的名称修改,因为它必须将几乎所有签名信息嵌入到名称中(所有参数类型),而在 C 中,修改后的名称通常与函数名称相同,或者前面有一个_
。
【讨论】:
是的,做到了。感谢您的帮助。以上是关于未定义的引用(但 nm 表示该函数存在)[重复]的主要内容,如果未能解决你的问题,请参考以下文章