对 c header 文件的未定义引用

undefined reference to c header file's

我想制作一个用于测试的库,为此,我想制作一个只返回一些 char* 的 c 程序。我是基于 cmake 构建的。这是我的 cmake 文件:

cmake_minimum_required(VERSION 2.8)
project(smc)
add_executable(${PROJECT_NAME} "main.c" "info.cpp")
target_link_libraries(${PROJECT_NAME}
    -lssh
    )
set(HDRS
    ${NMEA_HDRS}
    info.h
    )

header:

#ifndef INFO_H
#define INFO_H

int sshConnection();
char* getcpuusage();

#endif // INFO_H

来源:

#include "info.h"
#include <libssh/libssh.h>
#include <stdio.h>
int sshConnection()
{
    ssh_session my_ssh_session = ssh_new();
    const void* ip = "localhost";
    if( my_ssh_session == NULL ) {
            printf( "Error creating ssh session" );
            return 1;
    }
    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
    ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "heydari.f");
    int rc = ssh_connect(my_ssh_session);
    if( rc != SSH_OK ) {
            printf("Error with connecting" );
            ssh_free(my_ssh_session);
            return -1;
    }

    rc = ssh_userauth_password(my_ssh_session, NULL, "heydari@linux");
    if( rc != SSH_AUTH_SUCCESS) {
            printf("Error with authorization %c " , ssh_get_error(my_ssh_session) );
            ssh_disconnect(my_ssh_session);
            ssh_free(my_ssh_session);
            return -1;
    }

}
char *getcpuusage()
{
    sshConnection();
    char * usage = "44%";
    return usage;
}

当我在 main.cpp 中使用此 header 文件时:

#include <stdio.h>
#include "info.h"
int main()
{
    char* f = getcpuusage();
    return 0;
}

我收到这个错误:

.../projects/smc/smc/main.c:-1: error: undefined reference to `getcpuusage'

我做cmake是不是错了?

首先,错误信息来自链接器,它没有找到符号getcpuusage

原因是,你的info.cpp是C++源文件,而main.c是C源文件。默认情况下(允许例如函数重载)C++ 对所有 C++ 函数执行所谓的 name-mangling,基本上将函数名称与其参数类型组合以创建符号名称(看起来很混乱对人类来说是混乱的)。源文件的文件名很重要,因为 cmake 决定了如何从中编译文件,所以在这种情况下,它用 C 编译器编译一个,另一个用 C++ 编译器编译。

有3种直接解法:

  1. 仅使用 C++,换句话说,将 main.c 重命名为 main.cpp .在这种情况下使用 C++ 头文件和库会很好,所以不要使用例如 stdio.h,更喜欢 C++ 库。

  2. 只使用C,换句话说,将info.cpp重命名为info.c(并从中删除任何 C++ 代码,但在本例中它没有任何代码)。

  3. 告诉 C++ 编译器不要进行名称修改。这可以在声明函数时使用 extern "c" 来完成(然后你不能使用重载):

info.h:


#ifndef INFO_H
#define INFO_H

#ifdef __cplusplus
// when included in C++ file, let compiler know these are C functions
extern "C" {
#endif

int sshConnection();
char* getcpuusage();

#ifdef __cplusplus
}
#endif

#endif // INFO_H