CGO 之 Dll调用
2016-07-05 15:24
246 查看
生成的dll库代码
导出函数def
go调用测试
// GoDll.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include <iostream> #include <cstdint> void __stdcall void_R0() { std::cout << __FUNCTION__ << std::endl; } void __stdcall void_R1(const char* name) { std::cout << __FUNCTION__ << " ----> " << name << std::endl; } void __stdcall void_R2(const char*name ,char **outName) { std::string _name = "HintSoft 新浩艺-"; _name += name; strcpy(*outName,_name.c_str()); } uint8_t __stdcall uint8_R1(char** outJson) { *outJson = new char[256]; memset(*outJson,0,256); strcpy(*outJson,"Hello -> 你被骗了,这里没有Json,只有中文"); return 1; } void __stdcall uint8_R1_free(char** outJson) { if(outJson == 0) return; if(*outJson == 0) return; delete [](*outJson); *outJson = nullptr; } typedef void (*CallBackFunType)(const char * in); void setCallBackFun(CallBackFunType func) { if(!func) { std::cout << __FUNCTION__ << " NULL ptr" << std::endl; } func("hello CallBackFuncType ---- setCallBackFun"); }
导出函数def
EXPORTS void_R0 @1 void_R1 @2 void_R2 @3 uint8_R1 @4 uint8_R1_free @5 setCallBackFun @6
go调用测试
package main import ( "fmt" "syscall" "unsafe" ) /* #include <stdio.h> // 如果要调用C.free 一定要在些包含对应的头文件 #include <stdlib.h> // 以下两种方式任选其一 void CallBackFun( char* in); //void CallBackFun( char* in) //{ // printf("%s\r\n",in); //} */ import "C" // export 必须要 //export CallBackFun func CallBackFun(in *C.char) { fmt.Print(C.GoString(in)) } func main() { fmt.Println("---------------------------------------------------------------") handle, err := syscall.LoadDLL("GoDll.dll") if err != nil { fmt.Println(err.Error()) return } fmt.Println(handle.Handle) fmt.Println(handle.Name) void_R0, err := handle.FindProc("void_R0") if err != nil { fmt.Println("void_R0 不存在", err.Error()) return } void_R1, err := handle.FindProc("void_R1") if err != nil { fmt.Println("void_R1 不存在", err.Error()) return } void_R2, err := handle.FindProc("void_R2") if err != nil { fmt.Println("void_R2 不存在", err.Error()) return } uint8_R1, err := handle.FindProc("uint8_R1") if err != nil { fmt.Println("uint8_R1 不存在", err.Error()) return } uint8_R1_free, err := handle.FindProc("uint8_R1_free") if err != nil { fmt.Println("uint8_R1_free 不存在", err.Error()) return } setCallBackFun, err := handle.FindProc("setCallBackFun") if err != nil { fmt.Println("setCallBackFun 不存在", err.Error()) return } fmt.Println("--------------------------函数加载成功-------------------------") // ------------------------------------------------------------------------- fmt.Println("---- void_R0") fmt.Println(void_R0.Addr()) void_R0.Call() // ------------------------------------------------------------------------- fmt.Println("\r\n\r\n---- void_R1") fmt.Println(void_R1.Addr()) name := C.CString("li_jian_xing") void_R1.Call((uintptr)(unsafe.Pointer(name))) C.free(unsafe.Pointer(name)) // ------------------------------------------------------------------------- // 创建数组,传入char** 取出C函数中的数据 fmt.Println("\r\n\r\n---- void_R2") fmt.Println(void_R2.Addr()) arg := make([]C.char, 1024) name = C.CString("li_jian_xing") void_R2.Call((uintptr)(unsafe.Pointer(name)), (uintptr)(unsafe.Pointer((&arg)))) C.free(unsafe.Pointer(name)) fmt.Println(C.GoString(&arg[0])) // ------------------------------------------------------------------------- // 传入char** 取出C函数分配的内存,处理完再释放 fmt.Println("\r\n\r\n---- uint8_R1") fmt.Println(uint8_R1.Addr()) var argc *C.char uint8_R1.Call((uintptr)(unsafe.Pointer(&argc))) fmt.Println(C.GoString(argc)) uint8_R1_free.Call((uintptr)(unsafe.Pointer(&argc))) // ------------------------------------------------------------------------- // 向dll 函数设定回调 fmt.Println("\r\n\r\n---- setCallBackFun") fmt.Println(setCallBackFun.Addr()) setCallBackFun.Call((uintptr)(unsafe.Pointer(C.CallBackFun))) handle.Release() // 释放dll 句柄 }
相关文章推荐
- SQLSERVER 中GO的作用详解
- 在Go语言程序中使用gojson来解析JSON格式文件
- 举例详解Go语言中os库的常用函数用法
- Go语言中函数的参数传递与调用的基本方法
- 深入解析Go语言的io.ioutil标准库使用
- GO语言的IO方法实例小结
- Go语言的os包中常用函数初步归纳
- Go语言中数组的基本用法演示
- GO语言类型转换和类型断言实例分析
- 深入解析Go语言编程中的递归使用
- 初步解读Golang中的接口相关编写方法
- Go语言实现的最简单数独解法
- 详解Golang编程中的常量与变量
- Go实现比较时间大小
- 深入剖析Go语言编程中switch语句的使用
- 简单讲解Go程序中使用MySQL的方法
- Go语言的Windows下环境配置以及简单的程序结构讲解
- 在Go程序中实现服务器重启的方法
- Go语言流程控制之goto语句与无限循环
- 在Mac OS上安装Go语言编译器的方法