目录结构
[root@localhost example03]# tree
.
├── library
│ ├── library-bridge.cpp
│ ├── library-bridge.h
│ ├── library.cpp
│ ├── library.hpp
└── main.go
各文件对应的代码
library.hpp
#pragma once
#include <string>
using namespace std;
class Foo {
public:
Foo(int value);
~Foo();
int value() const;
string testString(string params);
private:
int m_value;
};
library.cpp
#include "library.hpp"
#include <iostream>
Foo::Foo(int value) : m_value(value) {
std::cout << "[c++] Foo::Foo(" << m_value << ")" << std::endl;
}
Foo::~Foo() { std::cout << "[c++] Foo::~Foo(" << m_value << ")" << std::endl; }
int Foo::value() const {
std::cout << "[c++] Foo::value() is " << m_value << std::endl;
return m_value;
}
string Foo::testString(string params) {
std::cout << "[c++] testString params is " << params << std::endl;
return params + " world!";
}
library-bridge.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void* LIB_NewFoo(int value);
void LIB_DestroyFoo(void* foo);
int LIB_FooValue(void* foo);
const char* LIB_TestString(char* params);
#ifdef __cplusplus
} // extern "C"
#endif
library-bridge.cpp
#include <iostream>
#include "library-bridge.h"
#include "library.hpp"
void* LIB_NewFoo(int value) {
std::cout << "[c++ bridge] LIB_NewFoo(" << value << ")" << std::endl;
Foo* foo = new Foo(value);
std::cout << "[c++ bridge] LIB_NewFoo(" << value << ") will return pointer "
<< foo << std::endl;
return foo;
}
// Utility function local to the bridge's implementation
Foo* AsFoo(void* foo) { return reinterpret_cast<Foo*>(foo); }
void LIB_DestroyFoo(void* foo) {
std::cout << "[c++ bridge] LIB_DestroyFoo(" << foo << ")" << std::endl;
AsFoo(foo)->~Foo();
}
int LIB_FooValue(void* foo) {
std::cout << "[c++ bridge] LIB_FooValue(" << foo << ")" << std::endl;
return AsFoo(foo)->value();
}
const char* LIB_TestString(char* params) {
std::cout << "[c++ bridge] LIB_TestString params is " << params << std::endl;
Foo foo(1);
return foo.testString(params).c_str();
//return const_cast<char*>(foo.testString(params).c_str());
//return new Foo()->testString(params);
}
main.go
package main
// #cgo CFLAGS: -I${SRCDIR}/library
// #cgo LDFLAGS: -lstdc++ -L./library -llibrary
// #include "./library-bridge.h"
import "C"
import "unsafe"
import "fmt"
type Foo struct {
ptr unsafe.Pointer
}
func NewFoo(value int) Foo {
var foo Foo
foo.ptr = C.LIB_NewFoo(C.int(value))
return foo
}
func (foo Foo) Free() {
C.LIB_DestroyFoo(foo.ptr)
}
func (foo Foo) value() int {
return int(C.LIB_FooValue(foo.ptr))
}
func (foo Foo) testString(params string) string {
return C.GoString(C.LIB_TestString(C.CString(params)))
}
func main() {
foo := NewFoo(42)
defer foo.Free() // The Go analog to C++'s RAII
fmt.Println("[go]", foo.value())
fmt.Println("----------------------")
params := "gohello"
result := foo.testString(params)
fmt.Println("string result = ", result)
}
方式一:调用静态链接库
编译静态链接库
cd library/
g++ -c library.cpp
g++ -c library-bridge.cpp
ar -crs liblibrary.a library.o library-bridge.o
编译完成后代码结构如下所示:
[root@localhost example03]# tree
.
├── library
│ ├── liblibrary.a
│ ├── library-bridge.cpp
│ ├── library-bridge.h
│ ├── library-bridge.o
│ ├── library.cpp
│ ├── library.hpp
│ └── library.o
└── main.go
运行
go run main.go
可得到如下结果:
[root@localhost example03]# go run main.go
[c++ bridge] LIB_NewFoo(42)
[c++] Foo::Foo(42)
[c++ bridge] LIB_NewFoo(42) will return pointer 0x236d2d0
[c++ bridge] LIB_FooValue(0x236d2d0)
[c++] Foo::value() is 42
[go] 42
----------------------
[c++ bridge] LIB_TestString params is gohello
[c++] Foo::Foo(1)
[c++] testString params is gohello
[c++] Foo::~Foo(1)
string result = gohello world!
[c++ bridge] LIB_DestroyFoo(0x236d2d0)
[c++] Foo::~Foo(42)
[root@localhost example03]#
方式二:调用动态链接库
生成动态链接库
gcc -fpic -shared library.cpp library-bridge.cpp -o liblibrary.so
运行
go run main.go
注意:调用动态库会有加载不到的情况
error while loading shared libraries: liblibrary.so: cannot open shared object file: No such file or directory
可以结合这篇文章来设置:https://blog.csdn.net/kenkao/article/details/93026902
配置完成后,需要运行ldconfig
参考文章
- https://stackoverflow.com/questions/1713214/how-to-use-c-in-go
- https://bastengao.com/blog/2017/12/go-cgo-cpp.html
- https://blog.csdn.net/Eric_zhang929/article/details/104926330
- https://blog.csdn.net/kenkao/article/details/93026902