go如何調用C動態(tài)庫函數(shù)
更新時間:2025年05月23日 08:39:06 作者:碼靈
這篇文章主要介紹了go如何調用C動態(tài)庫函數(shù)的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
go調用C動態(tài)庫函數(shù)
方式一
- 直接調用動態(tài)庫,需要有頭文件;
- 沒有的話還需要自己再寫一個動態(tài)庫去調用;
- 過程比較繁瑣;
方式二
- 直接使用cgo調用;
- 使用dlopen去調用動態(tài)庫;
- 比較方便和go代碼在一個文件上;
1 字符串、int相互轉換;
2內存手動釋放;
!!! go 調用C動態(tài)庫不支持交叉編譯!
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動態(tài)庫
void* handle = dlopen("libhardwareInfo2.so", RTLD_LAZY);
struct Hardware_API_Result (*getSysT)();
//根據(jù)動態(tài)鏈接庫操作句柄與符號,返回符號對應的地址
getSysT = dlsym(handle, "get_system_time");
//struct MidStruct midres;
struct Hardware_API_Result r;
r = getSysT();
//static char* cj="404"; 不能使用靜態(tài)變量,多個線程調用,值會覆蓋;測試:多次調用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"
)
/*
獲取系統(tǒng)時間
json 格式:{"local_time":2020-03-23 03:02:46.795268}
*/
func getSystime() string {
//c中指針
sip:=C.getSysTime()
//轉變?yōu)間o字符串
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動態(tài)持久化任務調度的強大庫使用實例
這篇文章主要為大家介紹了Golang AGScheduler動態(tài)持久化任務調度的強大庫使用實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10

