go调用C动态库函数

方式一:直接调用动态库,需要有头文件;没有的话还需要自己再写一个动态库去调用;过程比较繁琐;

方式二:直接使用cgo调用;使用dlopen去调用动态库;比较方便和go代码在一个文件上;

    1 字符串、int相互转换;

    2内存手动释放;

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

package main


/*
#include 
#include 
#include 
#include 
#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]))

 

你可能感兴趣的:(go)