go如何调用C动态库函数

作者:

文章目录
  • 以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。 您可能感兴趣的文章: Golang使用CGO与Plugin技术运行加载C动态库 go语言调用c语言的so动态库的实现 Go调用C++动态库实现车牌识别的示例代码 C语言调用go生成的动态库的踩坑过程解析 golang动态库(so)生成与使用方法教程
  • 目录
    • go调用C动态库函数
      • 方式一
      • 方式二
    • 总结

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

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

      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]))

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。

      您可能感兴趣的文章:

      • Golang使用CGO与Plugin技术运行加载C动态库
      • go语言调用c语言的so动态库的实现
      • Go调用C++动态库实现车牌识别的示例代码
      • C语言调用go生成的动态库的踩坑过程解析
      • golang动态库(so)生成与使用方法教程

      站内搜索