【问题标题】:Getting error : "could not determine kind of name for C.functionName()" with cgo出现错误:“无法使用 cgo 确定 C.functionName() 的名称类型”
【发布时间】:2021-10-29 09:34:06
【问题描述】:

我正在尝试使用 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()
}

【问题讨论】:

    标签: c++ c go linker cgo


    【解决方案1】:

    cgo 只懂 C,不懂 C++。在将文件构建为普通 C 源文件时,.h 文件中的 #ifdef __cplusplus 指令会删除其内容。

    此外,C++ 方法 infinispan::hotrod::BaseCounterImpl::getNameinfinispan::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 包装器函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      • 2018-03-31
      • 1970-01-01
      相关资源
      最近更新 更多