GO 和C 的相互调用(1)

爱上了Golang,C/C++ 又不想放弃。好在Go 语言提供了和C语言相互调用的机制(CGO )。包括下面几个问题

  •    C/C++ 调用Go 程序编写的库。
  •    go 语言调用C/C++ 动态和静态库。
  •    go 语言调用 C语言的回调程序(Callback)
  •    函数之间传递参数

本文先讨论前面两个问题。

Go 和C++ 相互调用是一个十分有意义的事情,go 语言在编写网络程序,云服务等程序时,效率要比C/C++ 高许多倍。使用Go 写一个Web server 只要几行而已。而C++ 在处理底层接口时更方便一点。

C/C++ 调用 Go

首先写一个go 程序

package main

import "C"

import (
    "fmt"
)
//export Foo
func Foo(a, b int) int {
    return a + b;
}

//export Bar
func Bar() {
    fmt.Println("Say Hello  From Go")
}

func main() {}

注意: 注释 //export Foo 和 //export Bar 表示输出 两个函数

编译

 go build -o golib.so -buildmode=c-shared *.go 

在目录中产生了两个文件:

golib.h

golib.so

C 语言主程序

#include "golib.h"
#include <stdio.h>

int main() {
    printf("%lld\n",Foo(1,2));
    Bar();
    return 0;
}

编译

 gcc callgo.c -o callgo ./golib.so  

Go 调用 C/C++

C 语言库代码(hello.c)

#include <stdio.h>

void hello(int i) {
  printf("Hello C: %d\n", i);
}

hello.h

void hello(int);

 

Go 调用 C 动态库

编译动态库

gcc -fPIC -shared -o libhello.so hello.c 

建立一个库目录mylib,将libhello.so 拷贝到 mylib 目录中。并且输出该路径路径:

export LD_LIBRARY_PATH=./mylib 

go代码

package main

// #cgo CFLAGS: -I./mylib
// #cgo LDFLAGS: -L./mylib -lhello
// #include "hello.h"
import "C"

import "fmt"

func main() {
  C.hello(C.int(12))
  fmt.Println("Hello Go");
}

go 程序编译

 go build CallC.go 

Go 调用 C 静态库

首先编译和建立c 静态库

 gcc -Wall -c hello.c
 ar -rv libhello.a hello.o  

将libhello.a 拷贝到mylib  目标中。

这里出现了问题,网络上的许多文章中都说GO 程序和动态连接是一样的,其实不然。go 程序应该为:

package main

// #cgo CFLAGS: -I./mylib
// #cgo LDFLAGS: ./mylib/libhello.a
// #include "hello.h"
import "C"

import "fmt"

func main() {
  C.hello(C.int(12))
  fmt.Println("Hello Go");
}

将cgo LDFLAGS 设定为静态文件名  //  #cgo LDFLAGS: ./mylib/libhello.a

而编译命令是一样的

 go build CallC.go 

猜你喜欢

转载自blog.csdn.net/yaojiawan/article/details/108991989
今日推荐