环境:centos 7.6.18
编译环境:go1.11.4 linux/amd64
、4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
动态库实现了三个功能,单个无参函数的;单个结构体函数;多个结构体函数
def.h
#ifndef _DEF_H_
#define _DEF_H_
// 结构体
struct userinfo
{
char* username;
int len;
};
#endif
hello.h
#ifndef _CALL_H_
#define _CALL_H_
#include "def.h"
void helloworld();
void store_jpg(char* name , int len);
void only_struct(struct userinfo* u);
void multi_struct(struct userinfo* u,int size);
#endif //_CALL_H_
hello.c
#include "hello.h"
#include
#include
// helloworl
void helloworld()
{
printf("hello world.\n");
}
// 指针和int 模拟存文件
void store_jpg(char* name ,int len)
{
FILE *fp = NULL;
fp = fopen( "file.jpg" , "w" );
fwrite(name, len , 1, fp );
fclose(fp);
}
// 调用结构体指针
void only_struct(struct userinfo* u)
{
char* name =u->username;
int len = u->len;
printf("call_only_struct:%s %d\n",name,len);
}
// 调用结构体指针,模拟结构体数组
void multi_struct(struct userinfo* u,int size)
{
int i = 0;
printf("call_multi_struct\n");
while (i < size)
{
char* name = u[i].username;
int len = u[i].len;
printf("username:%s, len:%d, size:%d\n",name,len,size);
i++;
}
}
测试动态库是否正常的c代码main.c
#include
#include "def.h"
// 调用 libhello.so 测试动态库
int main()
{
helloworld();
struct userinfo u = {"shadiao wangyou",sizeof("shadiao wangyou")};
only_struct(&u);
return 0;
}
实现两个接口,一个打印hello world
,一个存储文件。
1)调用单个的无参函数
2)调用指针和长度,在大部分的场景中都会用到
3)调用单个的结构体,数据结构使用的是c代码中定义的结构
4)调用多个结构体
package main
/*
#cgo CFLAGS : -I../c
#cgo LDFLAGS: -L../c -lhello
#include "hello.h"
#include
#include
*/
import "C"
import (
"os"
"unsafe"
"fmt"
)
func main(){
call_helloworl()
call_store_file()
call_only_struct()
call_multi_struct()
}
func call_helloworl(){
C.helloworld()
}
func call_store_file(){
f,err:=os.Open("1.jpg")
if err!=nil{
panic(err)
}
defer f.Close()
buf:=make([]byte,1024*10)
if n,err:=f.Read(buf);err!=nil{
panic(err)
}else{
cs:=C.CString(string(buf[0:n]))
defer C.free(unsafe.Pointer(cs))
C.store_jpg(cs, C.int(n))
}
}
func call_only_struct(){
var userinfo C.struct_userinfo
cs:= C.CString("shadiao wangyou")
defer C.free(unsafe.Pointer(cs))
userinfo.username =cs
userinfo.len = C.int(len("shadiao wangyou"))
C.only_struct(&userinfo)
}
func call_multi_struct(){
var userinfos []C.struct_userinfo
for i:=0;i<2;i++{
var ui C.struct_userinfo
s:=fmt.Sprintf("%s-%d","shadiao wangyou",i)
cs:= C.CString(s)
defer C.free(unsafe.Pointer(cs))
ui.username =cs
ui.len = C.int(len(s))
userinfos=append(userinfos,ui)
}
C.multi_struct(&userinfos[0],C.int(len(userinfos)))
}
cgo
├── c
│ ├── hello.c
│ ├── hello.h
│ ├── libhello.a
│ ├── libhello.so
│ ├── main
│ ├── main.c
│ ├── make.sh
│ └── static_main
└── go
├── libhello.so
├── main
└── main.go
编译脚本make.sh
#/bin/bash
echo "static lib"
rm -rf ./*.o
rm -rf ./*.a
rm -rf main
gcc -c -o hello.o hello.c
ar -rc libhello.a hello.o
gcc main.c libhello.a -L. -o static_main
rm -rf ./*.o
echo "lib"
rm -rf /usr/lib64/libhello.so
gcc -fPIC -shared hello.c -o libhello.so
sudo cp libhello.so /usr/lib64/
gcc main.c -L. -lhello -o main