前言:Golang调用是通过cgo完成的,Golang调用C++,则需要将C++函数导出包装为C函数,然后再通过cgo完成调用,话不多说,直接给出调用示例。
开发工具:Clion,Goland
首先msys2,通过msys2安装mingw,cmake等开发C,C++的环境,golang开发环境自行搭建。
本次示例目录结构如下:
-->cgo 项目根目录
---->cshare C项目根目录
------>cplusplus C++项目根目录
-------->library.h C++库头文件
-------->library.cpp C++库源文件
-------->library_wrapper.h C++库包装头文件
-------->library_wrapper.cpp C++库包装源文件
------>library.h C库头文件
------>library.c C库源文件
------>library_wrapper.h C++库头文件
------>main.c C执行文件
------>CMakeList.txt CMake文件
---->add.go golang调用C++示例
---->file_reader.go golang调用C示例
Golang调用C示例过程说明
1.在library.h中声明一个golang要调用的函数,如下所示
#ifndef CSHARE_LIBRARY_H #define CSHARE_LIBRARY_H void hello(); //简单测试示例 void readFile(const char* filename); //golang通过C读取任意位置文件,读取255个字符 int add(int x,int y);//golang通过C调用C++的加法 #endif //CSHARE_LIBRARY_H
2.在library.c中实现library.h中声明的函数,如下所示
#include "library_wrapper.h" #include "library.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> void hello() { printf("hello,world!\n"); } void readFile(const char *filename) { FILE *fp; char buff[255]; fp = fopen(filename, "r"); if (fp == NULL) { printf("Filename:%s,Open file failed:%s\n", filename, strerror(errno)); return; } fgets(buff, 255, (FILE *) fp); printf("%s\n", buff); fclose(fp); } int add(int x, int y) { int sum = addWrapper(x, y); return sum; }
3.在file_reader.go中实现对C方法readFile的调用
package main //#include "cshare/library.c" import "C" import ( "flag" "fmt" "os" ) func main() { var help bool var file string var len int flag.IntVar(&len,"len",0,"golang c file reader will read this file with this len") flag.StringVar(&file, "file", "", `golang c file reader will read this file`) flag.BoolVar(&help, "help", false, "show golang c file reader usage") flag.Usage = func() { _, _ = fmt.Fprintln(os.Stdin, `golang c file reader 1.0`) _, _ = fmt.Fprintln(os.Stdin, `options:`) flag.PrintDefaults() } flag.Parse() if help { flag.Usage() } if file != "" { C.readFile(C.CString(file)) } }
至此Golang调用C的过程结束,在Golang中调用C库源文件,不需要调用C库的头文件,因为C库源文件中已经导入过C库头文件,所以不用再Golang文件导入了。