golang中使用cgo调用c++程序

1 背景

这两天在考虑使用golang搭建一个http服务,调用别人的linux sdk。由于linux sdk是用c写的,直接使用cgo调用c是很方便的,但是个人想使用c++来调用c的函数,封装成c++语法,c++可以使用一些库,对于开发是比较方便的,所以就得考虑使用cgo调用c++程序。

网上一搜,目前实现cgo调用c++主要有三种方式:
1 swig
2 swift
3 使用c包装c++,然后cgo调用c

对于以上3种方式,第2种我是没看过,第1种就浏览了下,没写过。主要是想用第3种,可以纯粹的写c++,c。

环境:
ubuntu 16 64bit (个人喜欢用centos 7.*)
gcc g++都是默认的。
golang gopath = /home/user/gopath

说明:以下代码是从网上下载的,但是别人的实现是要编译可执行文件,即go build, 然后执行可执行文件。(源码地址:draffensperger/go-interlang )不能通过go run *.go 来执行,很嫌弃这种,麻烦,所以自己就来该动了。自己项目中的代码就不能放在这了,原理都是相同的。

2 golang 调用c++ 实例

源码: example
目录结构:
exampleOne 一定要放在src中,防止找不到包

$gopath:
    src - exampleOne 
             -  main.go
             -  temp
               - one.go,  point.cxx  point.hxx  wrap_point.cxx  wrap_point.hxx 

temp中是从网上下的源码,不作改动。
然后就可以执行:

go run main.go

文件与代码:
main.go

// main.go
package main
import (
"funcExample/temp"
)

func main () {
   temp.P()
}

temp 下的 one.go

// one.go
package temp

// #include "wrap_point.hxx"
import "C"

import "fmt"

func init() {
        fmt.Println("Hi from Go, about to calculate distance in C++ ...")
        distance := C.distance_between(1.0, 1.0, 2.0, 2.0)
        fmt.Printf("Go has result, distance is: %v\n", distance)
}
func P() {
        distance := C.distance_between(1.0, 1.0, 2.0, 2.0)
       fmt.Println(distance)
}

temp下的 point.cxx

// point.cxx
#include "point.hxx"
#include 
#include 

Point::Point(double x, double y): x_(x), y_(y) {
}

double Point::distance_to(Point p) {
  std::cout << "C++ says: finding distance between (" << x_ << "," << y_
    << "), and (" << p.x_ << "," << p.y_ << ")" << std::endl;
  double x_dist = x_ - p.x_;
  double y_dist = y_ - p.y_;
  return sqrt(x_dist * x_dist + y_dist * y_dist);
}

temp 下的 point.hxx

// point.hxx 
#ifndef POINT_H
#define POINT_H

class Point {
public:
  Point(double x, double y);
  double distance_to(Point p);
private:
  double x_, y_;
};
#endif

temp 下的wrap_point.cxx

// wrap_point.cxx
#include "wrap_point.hxx"
#include "point.hxx"

double distance_between(double x1, double y1, double x2, double y2) {
  return Point(x1, y1).distance_to(Point(x2, y2));
}

temp 下的 wrap_point.hxx

// wrap_point.hxx
#ifndef WRAP_POINT_H
#define WRAP_POINT_H

// __cplusplus gets defined when a C++ compiler processes the file
#ifdef __cplusplus
// extern "C" is needed so the C++ compiler exports the symbols without name
// manging.
extern "C" {
#endif
double distance_between(double x1, double y1, double x2, double y2);
#ifdef __cplusplus
}
#endif
#endif

对于以上的代码自己不做过多说明,都是c/c++ 的用法。
关于cgo语法类型与c的对应关系,可以直接查看cgo文档 command cgo,cgo除了提供直接与c数据类型的对应类型,还支持使用函数将golang数据类型转换成c的数据类型,比如 func C.CString(string) *C.char 见文档说明。

3 其他实例

github源码中的exmapleTwo 是与以上实例类似的。只不过以上对c++类的包装使用比上面更详细。其中的temp也是从网上下载的源码。
更多cgo设置文件include, lib的方式可以看看其他相关资料,此处懒得打字。

你可能感兴趣的:(go)