赞
踩
[root@localhost example03]# tree
.
├── library
│ ├── library-bridge.cpp
│ ├── library-bridge.h
│ ├── library.cpp
│ ├── library.hpp
└── main.go
#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;
};
#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!"; }
#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
#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); }
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
在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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。