猿问

cgo 调用 C++ 中定义的函数(位于命名空间中)

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


我看过这个:How to use C++ in Go? 这是有道理的,但其中不涉及名称空间。


这是有问题的 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 包装器来避免这个问题吗?


喵喔喔
浏览 215回答 1
1回答

慕哥6287543

我通过创建 C 包装头文件来解决这个问题。然后我创建了一个 CPP 文件,它将所述 C 接口与库 CPP 标头和库桥接起来。C 标头将我的库对象理解为 void 指针,并且我的 CPP 实现必须对其进行强制转换才能访问其所有函数。这extern "C"部分非常重要,可以防止 Go 崩溃——它可以防止 CPP 编译器修改函数名称。当然,还要将二进制文件链接到正确的 LDFLAGS。凤凰.htypedef void CTalon;#ifdef __cplusplusextern "C" {#endifCTalon* 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. Optionalnamespace ctre { // Specific to my library which has a lot of long namespaces. Unrelated to problem&nbsp; &nbsp; using ctre::phoenix::motorcontrol::ControlMode;&nbsp; &nbsp; using ctre::phoenix::motorcontrol::can::TalonSRX;}extern "C" {&nbsp; &nbsp; CTalon* CTRE_CreateTalon(int port) {&nbsp; &nbsp; &nbsp; &nbsp; return (CTalon*) new ctre::TalonSRX(port);&nbsp; &nbsp; }&nbsp; &nbsp; void CTRE_Set(CTalon* talon, double output) {&nbsp; &nbsp; &nbsp; &nbsp; TALON(talon)->Set(ctre::ControlMode::PercentOutput, output);&nbsp; &nbsp; }&nbsp; &nbsp; void CTRE_Follow(CTalon* slave, CTalon* master) {&nbsp; &nbsp; &nbsp; &nbsp; TALON(slave)->Follow(*(TALON(master)));&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答