go如何调用C动态库函数

 更新时间:2025年05月23日 08:39:06   作者:码灵  
这篇文章主要介绍了go如何调用C动态库函数的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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 AGScheduler动态持久化任务调度的强大库使用实例

    Golang AGScheduler动态持久化任务调度的强大库使用实例

    这篇文章主要为大家介绍了Golang AGScheduler动态持久化任务调度的强大库使用实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Go归并排序算法的实现方法

    Go归并排序算法的实现方法

    归并排序采用的也是分治的策略,把原本的问题先分解成一些小问题进行求解,再把这些小问题各自的答案修整到一起得到原本问题的答案,从而达到分而治之的目的,对Go归并排序算法相关知识感兴趣的朋友一起看看吧
    2022-04-04
  • go语言中的interface使用实例

    go语言中的interface使用实例

    这篇文章主要介绍了go语言中的interface使用实例,go语言中的interface是一组未实现的方法的集合,如果某个对象实现了接口中的所有方法,那么此对象就实现了此接口,需要的朋友可以参考下
    2015-05-05
  • Go  import _ 下划线使用

    Go  import _ 下划线使用

    这篇文章主要为大家介绍了Go  import下划线_使用小技巧,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • go连接kafka的实现示例

    go连接kafka的实现示例

    本文主要介绍了go连接kafka的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • golang 项目打包部署环境变量设置方法

    golang 项目打包部署环境变量设置方法

    最近将 golang 项目打包部署在不同环境,下面分享一下我的心得体会,对golang 项目打包部署环境变量设置方法感兴趣的朋友一起看看吧
    2024-07-07
  • golang的Pseudo-versions使用问题解析

    golang的Pseudo-versions使用问题解析

    这篇文章主要为大家介绍有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪了golang的Pseudo-versions使用问题解析,
    2023-07-07
  • golang 归并排序,快速排序,堆排序的实现

    golang 归并排序,快速排序,堆排序的实现

    本文主要介绍了golang 归并排序,快速排序,堆排序的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 试了下Golang实现try catch的方法

    试了下Golang实现try catch的方法

    虽然在使用Golang的时候发现没有try catch这种错误处理机制但是想一想golang作为一门优雅的语言,似乎也是情理之中。那么够怎么捕获异常呢,本文就来介绍一下
    2021-07-07
  • golang如何获得一个变量的类型

    golang如何获得一个变量的类型

    这篇文章主要介绍了golang获得一个变量类型的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05

最新评论