开发者

go如何调用C动态库函数

目录
  • go调用C动态库函数
    • 方式一
    • 方式二
  • 总结

    go调用C动态库函数

    方式一

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

    方式二

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

    1 字符串、int相互转换;

    2内存手动释放;

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

    package mai编程n
    
    
    /*
    #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";  不能使用静态变量,多个线程调用,值会覆盖;测试:多次javascript调用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);
    http://www.devze.com	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.androidstart4G()
    	//转换成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]))

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜