c++ - undefined reference (但 nm 说该函数存在)

标签 c++ eclipse gcc

<分区>

我有一个来自相机制造商的库,在提供的演示代码中,一个名为 metadata_init() 的函数工作正常,但在我的代码中,我收到 undefined reference 错误。

演示代码的 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 是一个 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"mangling 一起使用。

与C相比,C++必须做一个复杂的名称重整,因为它必须将几乎所有的签名信息嵌入到一个名字中(所有参数类型),而在C中,重整后的名字通常与函数名相同,或者有一个 _ 前缀。

关于c++ - undefined reference (但 nm 说该函数存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45054077/

相关文章:

android - 从 Assets 读取文本文件时出现奇怪的行为

java - 将 mysql 连接器添加到 eclipse 中的 maven/nexus 构建

eclipse - 是否可以在 Eclipse 的 EGit 中将暂存/未暂存视为树

c++ - 递归 enable_if 和类型转换

c++ - 将字符串列表输出到 ostream

windows - 如何在 Eclipse 中打开文件并跳转到特定行?

c++ - "72"对 "gcc72-c++"意味着什么

c - -pie 究竟做了什么?

c - gcc 生成函数和变量名称列表

c++ - Libtiff 的 TIFFOpenW 抛出异常