首页 > 解决方案 > 在 C++ 中使用 Go

问题描述

linux Debian 克星

去版本 go1.11.6 linux/amd64

gcc 版本 8.3.0 (Debian 8.3.0-6)

libmylib.go

package main

import "C"

import (
    "fmt"
)

func say(text string) {
    fmt.Println(text)
}

func main(){}

mylib.h

#ifndef MY_LIB_H
#define MY_LIB_H

#include <string>

void say(std::string text);

#endif

主文件

#include <string>
#include "mylib.h"

using namespace std;

int main() {
    string text = "Hello, world!";

    say(text);

    return 0;
}

CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go

g++ -L/path/to/lib/ -lmylib main.cpp -o my-test-program

/usr/bin/ld: /tmp/ccu4fXFB.o: 在函数'main'中: main.cpp:(.text+0x53): undefined reference to `say(std::__cxx11::basic_string<char, std:: char_traits, std::allocator >)'
collect2: 错误: ld 返回 1 退出状态

有变化:package main -> package mylib

CGO_ENABLED=1 go build -o libmylib.so -buildmode=c-shared libmylib.go

-buildmode=c-shared 只需要一个主包

标签: c++goshared-objectsobject-files

解决方案


您必须使用GoString而不是std::string在 C++ 版本中。您收到的错误消息是由于类型不匹配,表现为链接时错误。

请参阅cgo 参考

这是一个工作示例。和你的有一些不同。该//export指令需要在生成的头文件中包含函数,参数是*C.char而不是stringGoString。C++ 代码使用由 cgo 生成的标头,并且必须从静态字符串中进行 const 移除强制转换(因为 go 没有类似 C 的 const)。

libmylib.go

package main

import "C"

import (
    "fmt"
)

//export say
func say(text *C.char) {
    fmt.Println(C.GoString(text))
}

func main() {}

主文件

#include "libmylib.h"

int main(void) {
    say(const_cast<char*>("hello world"));

    return 0;
}

命令

这编译为 go 文件,生成libmylib.solibmylib.h在当前目录中。

go build -o libmylib.so -buildmode=c-shared libmylib.go

编译 C++ 程序,将其链接到上面的共享库:

g++ -L. main.cpp -lmylib -o hello_program

要运行程序,LD_LIBRARY_PATH需要设置到当前目录。如果安装了程序并将共享库放在合理的位置,那将是不同的。

LD_LIBRARY_PATH=. ./hello_program

推荐阅读