Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > go调用C动态库函数

go如何调用C动态库函数

作者:码灵

这篇文章主要介绍了go如何调用C动态库函数的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

go调用C动态库函数

方式一

方式二

1 字符串、int相互转换;

2内存手动释放;

!!! go 调用C动态库不支持交叉编译!

package main


/*
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#cgo LDFLAGS: -ldl

struct Hardware_API_Result {
   int  result;
   char json[256];
};


char* getSysTime(){
   //  手动加载指定位置的so动态库
	void* handle = dlopen("libhardwareInfo2.so", RTLD_LAZY);
	struct Hardware_API_Result (*getSysT)();

	//根据动态链接库操作句柄与符号,返回符号对应的地址
	getSysT = dlsym(handle, "get_system_time");

	//struct MidStruct midres;
	struct Hardware_API_Result r;
	r = getSysT();

	//static char* cj="404";  不能使用静态变量,多个线程调用,值会覆盖;测试:多次调用go中日志输出成乱码
	char * cj;
	cj = (char *)malloc(256);
	strcpy(cj,"404");
	//
	if(r.result==0){
	   strcpy(cj,r.json);
	}
	dlclose(handle);
	return cj;
}
int start4G(){
	void* handle = dlopen("libhardwareInfo2.so", RTLD_LAZY);
	int (*start4G)();
	start4G = dlsym(handle, "start_4g");
	int rv=start4G();
	dlclose(handle);
	return rv;
}

int ping(char* cip){
    void* handle = dlopen("libhardwareInfo2.so", RTLD_LAZY);
	struct Hardware_API_Result (*midFuncName)( char* );
    midFuncName = dlsym(handle, "ping");
	struct Hardware_API_Result midres;
    midres=midFuncName(cip);
	int rvi=midres.result;
    dlclose(handle);

    return rvi;
}


*/
import "C"
import (
	"fmt"
	"unsafe"
)


/*
获取系统时间
json 格式:{"local_time":2020-03-23  03:02:46.795268}
*/
func getSystime() string {
    //c中指针
	sip:=C.getSysTime()
	//转变为go字符串
	si:=C.GoString(sip)
	//释放c中指针
	C.free(unsafe.Pointer(sip))
	return  si
}
/*
启动4g,启动成功返回0
*/
func start4G() int{
	//c类型
	mrv:=C.start4G()
	//转换成go int类型
	rv:=int(mrv)
	return rv
}


/**
判断某ip可否ping通,值为0表示通
*/
func ping(ip string)int{
	cip := C.CString(ip)
	mrv:=C.ping(cip)
	rv:=int(mrv)
	C.free(unsafe.Pointer(cip))
	return rv
}

参考方法1

C.char  
C.schar (signed char)  
C.uchar (unsigned char)  
C.short  
C.ushort (unsigned short)  
C.int  
C.uint (unsigned int)  
C.long  
C.ulong (unsigned long)  
C.longlong (long long)  
C.ulonglong (unsigned long long)  
C.float  
C.double.   
  
  
unsafe.Pointer (void*)  
  
// Go string to C string  
func C.CString(string) *C.char  
  
var val []byte  
(*C.char)(unsafe.Pointer(&val[0]))

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文