c++ - cgo 调用在 C++ 中定义的函数(在命名空间中)

标签 c++ go cgo

我有一个我想使用的库,它只提供 C++ 头文件和一个静态库。 Go 无法解析它所在的命名空间。

我看过这个:How to use C++ in Go?这是有道理的,但那里不涉及 namespace 。

这是有问题的 C++ 代码,当导入时会导致问题(仅显示开头):

#pragma once
#include <stdint.h>

namespace ctre {
namespace phoenix {

编译结果如下:

./include/ctre/phoenix/ErrorCode.h:4:1: error: unknown type name 'namespace'
 namespace ctre {
 ^~~~~~~~~
./include/ctre/phoenix/ErrorCode.h:4:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
 namespace ctre {

有什么方法可以提供一个 C 包装器来避免这个问题?

最佳答案

我通过创建 C 包装器头文件解决了这个问题。然后我创建了一个 CPP 文件,它将所述 C 接口(interface)与库 CPP 头文件和库桥接起来。

C 头文件将我的库对象理解为空指针,我的 CPP 实现必须转换它才能访问它的所有函数。

extern "C" 部分非常重要,可以防止 Go 崩溃 - 它可以防止 CPP 编译器混淆函数名。

当然,还要将二进制文件与正确的 LDFLAGS 链接起来。

凤凰.h

typedef void CTalon;

#ifdef __cplusplus
extern "C" {
#endif

CTalon* CTRE_CreateTalon(int port);

void CTRE_Set(CTalon* talon, double output);

void CTRE_Follow(CTalon* slave, CTalon* master);

#ifdef __cplusplus
}
#endif

凤凰.cpp

#include "phoenix.h" // My C wrapper header

#include "ctre/phoenix/motorcontrol/can/TalonSRX.h" // Actual CPP header from library

#define TALON(ctalon) ((ctre::TalonSRX*) ctalon) // Helper macro to make converting to library object easier. Optional

namespace ctre { // Specific to my library which has a lot of long namespaces. Unrelated to problem
    using ctre::phoenix::motorcontrol::ControlMode;
    using ctre::phoenix::motorcontrol::can::TalonSRX;
}

extern "C" {
    CTalon* CTRE_CreateTalon(int port) {
        return (CTalon*) new ctre::TalonSRX(port);
    }

    void CTRE_Set(CTalon* talon, double output) {
        TALON(talon)->Set(ctre::ControlMode::PercentOutput, output);
    }

    void CTRE_Follow(CTalon* slave, CTalon* master) {
        TALON(slave)->Follow(*(TALON(master)));
    }
}

关于c++ - cgo 调用在 C++ 中定义的函数(在命名空间中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58577007/

相关文章:

go - 如何将 *_Ctype_char 转换为 *_Ctype_uchar

C++ 错误 : terminate called after throwing an instance of 'std::bad_alloc'

c++ - 将二维数组作为参数传递

c++ - 如何在c++中使用每个循环

golang 仅在作者进行更改时才阻止读者

go - 在Golang中全局设置时区

go - 我是否必须释放使用 Cgo 创建的结构?

C调用Go导出函数

C++使用配置类从txt文件设置变量值

go - 为什么 Go 没有三元条件运算符