首页 > 编程语言 >为 C++程序添加 C 接口

为 C++程序添加 C 接口

时间:2022-10-19 23:11:07浏览次数:53  
标签:set CMAKE animal 接口 PROJECT 添加 C++ ANIMAL name

为 C++ 程序添加 C 语言接口总共有两个要注意的点,如下

  1. 要在接口定义中添加 extern "C" 的声明
  2. 进行链接时需要使用 C++ 的标准库

原始的 C++ 程序

animal.h
#ifndef _ANIMAL
#define _ANIMAL

class ANIMAL
{
public:
    ANIMAL(const char *);
    ~ANIMAL();
    char *getname(void);

private:
    char *name;
};

#endif // _ANIMAL
animal.cpp
#include "animal.h"
#include <string.h>

ANIMAL::ANIMAL(const char *data) //构造函数
{
    name = new char[64];
    strcpy(name, data);
}

ANIMAL::~ANIMAL() //析构函数
{
    if (name)
    {
        delete[] name;
        name = NULL;
    }
}

char *ANIMAL::getname(void)
{
    return name;
}

C 语言接口

animal_api.h
#ifndef _ANIMAL_API
#define _ANIMAL_API
#ifdef __cplusplus
extern "C"
{
#endif
    typedef void *animal_t;
    animal_t animal_create(const char *_name);
    void animal_print(animal_t _animal);
    void animal_destroy(animal_t _animal);
#ifdef __cplusplus
}
#endif
#endif // _ANIMAL_API
animal_api.cpp
#include "animal.h"
#include "animal_api.h"
#include <assert.h>
#include <iostream>
using namespace std;

void *animal_create(const char *name)
{
    ANIMAL *animal = new ANIMAL(name);
    return animal;
}

void animal_print(void *handle) //对外接口,而且必须有一个非类中方法,才能被C调用
{
    assert(handle);
    cout << "animal name is: "
         << ((ANIMAL *)handle)->getname()
         << endl;
}

void animal_destroy(void *handle)
{
    assert(handle);
    delete (ANIMAL *)handle;
}

在 animal_api.h 中出现的 extern "C" 是为了将函数声明为 C 类型,编译时,C++ 的函数命名方式与 C 不一样,如果不显式把函数声明为 C 类型,编译器就会按照 C++ 的命名方式去查找符号,结果肯定是找不到的,从而出现函数未定义的错误。接口实现程序的文件名使用 cpp 而不是 c,是因为 C 不认识 class 这个关键字,会导致编译错误。

测试文件

main.c
#include "animal_api.h"

int main(int argc, char *argv[])
{
    animal_t a = animal_create("dog");
    animal_print(a);
    animal_destroy(a);
    return 0;
}

编译文件

CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
# 需要在命令中设置 CMAKE_PREFIX_PATH 的值
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_COMPILER ${CMAKE_PREFIX_PATH}/bin/gcc.exe)
set(CMAKE_C_FLAGS "-Wall -Wshadow")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_COMPILER ${CMAKE_PREFIX_PATH}/bin/g++.exe)
set(CMAKE_CXX_FLAGS "-Wall -Wshadow")
# 同时启用 C 和 C++
project(main VERSION 0.1.0 LANGUAGES C CXX)
# 设置编译类型为 Debug
set(CMAKE_BUILD_TYPE Debug)
# 设置二进制文件输出目录
set(PROJECT_BINARY_DIR ${PROJECT_SOURCE_DIR}/build)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})

aux_source_directory(. PROJECT_SRCS)
add_executable(${PROJECT_NAME} ${PROJECT_SRCS})

如果使用自己编写的 Makefile 进行编译,进行链接时,需要使用 C++ 的标准库,否则会出现标准库函数未定义的错误

标签:set,CMAKE,animal,接口,PROJECT,添加,C++,ANIMAL,name
From: https://www.cnblogs.com/lonelyraft/p/add_c_ifs_for_cpp.html

相关文章