c++ - 出现错误:“无法使用 cgo 确定 C.functionName() 的名称类型”
问题描述
我正在尝试使用 Go 包装 C++ 库。在这里,我有一个头文件和一个 CPP 文件,我已经在 Go 中为它编写了一个包装器并试图调用它,但我得到了错误:
could not determine the kind of name for C.getName
could not determine kind of name for C.reset
所有三个文件都在同一个目录中,从该目录使用的命令是:
去构建 CountersImpl.go
其他详细信息:Windows 10-64,使用 Vscode,go 版本:1.16.4
文件名为 CountersImpl.h的文件中的几行
#ifndef SRC_HOTROD_API_COUNTERSIMPL_H_
#define SRC_HOTROD_API_COUNTERSIMPL_H_
#ifdef __cplusplus
#include "infinispan\hotrod\CounterConfiguration.h"
#include "hotrod\impl\RemoteCounterManagerImpl.h"
#include <string>
#include <future>
extern "C" {
#endif
#ifdef __cplusplus
namespace infinispan {
namespace hotrod {
class BaseCounterImpl: public virtual Counter {
public:
BaseCounterImpl(RemoteCounterManagerImpl& rcm, std::string name, CounterConfiguration configuration) :
rcm(rcm), name(name), configuration(configuration), removed(false) {
}
std::string getName() {
return name;
}
CounterConfiguration getConfiguration() {
return configuration;
}
void setRemoved() {
removed = true;
}
void reset();
void remove();
virtual long getValue();
const void* addListener(const event::CounterListener* listener);
void removeListener(const void* handler);
virtual ~BaseCounterImpl() {
}
CountersImpl.cpp
#include <hotrod\api\CountersImpl.h>
#include "hotrod\impl\operations\CounterOperations.h"
namespace infinispan {
namespace hotrod {
using namespace infinispan::hotrod::operations;
void BaseCounterImpl::reset() {
ResetCounterOperation op(*rcm.codec, rcm.transportFactory, rcm.topology, 0, name);
op.execute();
}
void BaseCounterImpl::remove() {
RemoveCounterOperation op(*rcm.codec, rcm.transportFactory, rcm.topology, 0, name);
op.execute();
setRemoved();
}
long BaseCounterImpl::getValue() {
GetCounterValueOperation op(*rcm.codec, rcm.transportFactory, rcm.topology, 0, name);
return op.execute();
}
CountersImpl.go
package CountersImpl
// #include "CountersImpl.h"
import "C"
import "fmt"
func main() {
fmt.Println("name : ",C.getName())
C.reset()
}
解决方案
cgo
只懂C,不懂C++。将文件构建为普通 C 源文件时,文件中的#ifdef __cplusplus
指令会删除其内容。.h
infinispan::hotrod::BaseCounterImpl::getName
此外,C++ 方法infinispan::hotrod::BaseCounterImpl::reset
并不是 C 函数名称。必须在对象BaseCounterImpl
上调用方法BaseCounterImpl
,而 C 对对象一无所知。
要从 C 调用 C++ 方法,通常需要定义相应的 C 包装函数,该函数接受指向this
对象的指针。有关更多详细信息,请参阅https://isocpp.org/wiki/faq/mixing-c-and-cpp。
一旦你有一个可以从 C 调用所需 C++ 函数的包装器,那么你就可以使用cgo
从 Go 调用 C 包装器函数。
推荐阅读
- sql - 带分区的 SQL 分组
- python - numpy 在两个 3d 矩阵上应用函数
- python - 是否可以在 Django 中制作移动应用程序?
- c# - 捆绑配置 xsd (bundleconfiguration.xsd)
- docker - 在 asp.net core docker 镜像中使用 wkhtml2pdf
- spring - 如何在 apache 中添加虚拟主机以指向部署在 Tomcat 上的 Spring REST API
- json - 在维基共享资源中按文件名查找图像
- ios - 带有多个内衬标签的estimatedRowHeight 导致单元格剪裁
- ios - iOS 文档/文件类型关联 - SVG
- android - 通过意图拍照返回 -1 作为结果代码