Golang編寫動態庫實現回調函數


Golang編寫動態庫實現回調函數

我們現在要做一個動態庫,但是C++實在是比較難,於是就想能不能用更簡單的golang來實現,golang也就是最近的版本才支持編譯成動態庫,在網上也沒找到可用的案例,好在我們解決了這個問題,這邊寫個筆記造福大眾。

main.go

package main
/*
#cgo CFLAGS: -I .
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef void (*callback)(void *,int);
extern void c_callback (void *,int);
extern callback _cb;
*/
import "C"
import (
	"encoding/json"
	"unsafe"
)

func funccallback(gostring string,goint int) {
	var cmsg *C.char = C.CString(gostring)
	var ivalue C.int = C.int(len(gostring))
	defer C.free(unsafe.Pointer(cmsg))
	C.c_callback(unsafe.Pointer(cmsg),ivalue)
}

//export register_rsucallback
func register_rsucallback(p C.callback) {
	C._cb = p;
	return
}

//export test_callback
func test_callback() {
	funccallback("hello,this is func callback.",123)
}

func main() {
}

bridge.go

package main

/*
#include <stdio.h>

typedef void (*callback)(void *,int);

callback _cb;

void c_callback(void* p,int i)
{
	_cb(p,i);
}
*/
import "C"

這樣寫完直接調用以下命令即可生成main.dll文件和main.h文件

winows編譯動態庫參考我的這篇文章

go build -o main.dll -buildmode=c-shared main.go bridge.go

然后就是C語言的測試程序調用

main.c

#include <stdio.h>
#include "main.h"

void gocallback(void* s,int len) {
     printf("raw data: %s\n",s);
}

int main() {
    // 注冊回調
    register_callback(gocallback);
    
    // 測試回調
    test_callback();
}

把C程序編譯一下即可測試。

有時我們需要在別的包里調用這個回調函數,這時可以做一個工具

utils包callbackutils.go

package utils

type funVarType func(string,int)

var FunVar func(string,int)

func SetFuncAddr(a funVarType) {
	FunVar=a
}

func Funccallbackutil (gostring string,i int) {
	FunVar(gostring,i)
}

在main.go中可以寫個init函數做個初始化

func init() {
	utils.SetFuncAddr(funccallback)
}

然后在寫一個測試的函數導出

//export test_callbackutil
func test_callbackutil() {
	utils.Funccallbackutil("hello this is func callbackutil test",123)
}

最后在main.c中調用測試函數即可測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM