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文件
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中调用测试函数即可测试。
Golang编写动态库实现回调函数的更多相关文章
- C#将C++动态库的回调函数封装成事件
关于C#调用C++动态库的文章很多,调用动态库中回调函数的方法也不在少数.但大多数调用回调函数的方法依然保留了C++的语法特点. 比如有一段C++的回调函数代码,为了表达它的意思,我把注释也粘贴了进来 ...
- Golang调用windows下的dll动态库中的函数
Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...
- Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件
Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...
- C++编写动态库(.DLL)给C#调用方法
1.在头文件中按照如下格式编写函数申明 extern "C" __declspec(dllexport) double __stdcall Add(double a, double ...
- windows下查看静态库和动态库的导出函数
在window下查看动态库的导出函数可以用vs自带的Depends工具: 查看静态库的信息要用命令行来实现: dumpbin /LINKERMEMBER Test.lib > 1 ...
- 从零开始编写动态库文件Makefile,C++版
这篇文章前,假设你已经看过<跟我一起写Makefile(一)>,陈皓写的那个. 对现有的一个C++动态库文件和调用程序,分别编写Makefile文件,从零开始,花了四天时间才搞清楚一半,生 ...
- golang调用动态库
测试动态库 test_so.h int test_so_func(int a,int b); test_so.c #include "test_so.h" int test_so_ ...
- 动态库(.so)隐藏函数名
一.偶遇 error: undefined reference to xxx 问题 尝试封装通用的接口到一个private.so,然后供客户端使用,private.so编译出来后由sample.cp ...
- 如何调用.so动态库中的函数,如何把自己的函数导出为.so的动态库函数供别人调用
调用.so中的函数和平常的函数没有区别,只是在编译连接时加上-lxxxx就行了.要生成.so库,则编译时用下面的语句:gcc -shared -Wl,-soname,libmyfun.so -o li ...
随机推荐
- Java安全之Filter权限绕过
Java安全之Filter权限绕过 0x00 前言 在一些需要挖掘一些无条件RCE中,大部分类似于一些系统大部分地方都做了权限控制的,而这时候想要利用权限绕过就显得格外重要.在此来学习一波权限绕过的思 ...
- Linux_rpm包管理
一.rpm包命令规范 1.包的组成 主包:bind-9.7.1-1.el5.i586.rpm 子包:bind-libs-9.7.1-1.el5.i586.rpm bind-utils-9.7.1-1. ...
- ELK学习实验014:Nginx日志JSON格式收集
1 Kibana的显示配置 https://demo.elastic.co/app/kibana#/dashboard/welcome_dashboard 环境先处理干净 安装nginx和httpd- ...
- shell基础之编译安装nginx
本节新学知识:if 判断语句 1 #!/bin/bash 2 #检查环境 3 SESTATE=`getenforce` 4 if [ $SESTATE != "Disabled" ...
- STM32的引脚的配置
http://blog.csdn.net/u010592722/article/details/45746079
- 并发王者课-青铜5:一探究竟-如何从synchronized理解Java对象头中的锁
在前面的文章<青铜4:synchronized用法初体验>中,我们已经提到锁的概念,并指出synchronized是锁机制的一种实现.可是,这么说未免太过抽象,你可能无法直观地理解锁究竟是 ...
- 3. servlet 和 springmvc框架关系
在springmvc上我们会编写很多相关的配置 编写springmvc.xml 配置映射器 配置 处理适配器 ... web.xml 配置前端控制器 (DispatcherServlet) 官网: h ...
- Docker学习(10) Docker的远程访问
Docker的远程访问 只需配置
- 将TVM集成到PyTorch上
将TVM集成到PyTorch上 随着TVM不断展示出对深度学习执行效率的改进,很明显PyTorch将从直接利用编译器堆栈中受益.PyTorch的主要宗旨是提供无缝且强大的集成,而这不会妨碍用户.为此, ...
- TensorRT 数据格式说明
TensorRT数据格式说明 NVIDIA TensorRT支持不同的数据格式.需要考虑两个方面:数据类型和布局. 数据类型格式 数据类型是每个单独值的表示.它的大小决定了数值的范围和表示的精度:分 ...