前言: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文件导入了。