Golang下通过syscall调用win32的dll(calling Windows DLLs from Go )
很多同学比如我虽然很喜欢golang,但是还是需要调用很多遗留项目或者其他优秀的开源项目,这时怎么办呢?我们想到的方法是用package里的syscall结合cgo
注意此处有坑:
在我调试时显示not enough arguments in call to syscall.Syscall
[ `go run dms.go` | done: 260.3744ms ]
# command-line-arguments
.\dms.go:72: not enough arguments in call to syscall.Syscall
exit status 2
因为我参照的是http://golang.org/pkg/syscall/#Syscall ,而其默认的是Linux/Unix的syscall API doc说明,
如何看windows的golang doc呢?
通过godoc command, 调用 godoc -http=:6060
然后在浏览器打开http://localhost:6060/pkg/syscall/#Syscall,这才是windows的golang pakage api
func Syscall
func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
Implemented in ../runtime/syscall_windows.goc.
func Syscall12
func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
func Syscall15
func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6
func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func Syscall9
func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
例子1:
func test(){
//首先,准备输入参数, GetDiskFreeSpaceEx需要4个参数, 可查MSDN
lpFreeBytesAvailable := int64(0) //注意类型需要跟API的类型相符
lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0)
//获取方法的引用
kernel32, _ := syscall.LoadLibrary("Kernel32.dll") // 严格来说需要加上 defer syscall.FreeLibrary(kernel32)
GetDiskFreeSpaceEx, _ := syscall.GetProcAddress(syscall.Handle(kernel32), "GetDiskFreeSpaceExW")
//执行之. 因为有4个参数,故取Syscall6才能放得下. 最后2个参数,自然就是0了
r, _, _ := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("C:"))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)), 0, 0)
// 注意, errno并非error接口的, 不可能是nil
// 而且,根据MSDN的说明,返回值为0就fail, 不为0就是成功
if r != 0 {
log.Printf("Free %dmb", lpTotalNumberOfFreeBytes/1024/1024)
}
}
例子2,弹出一个简单的对话框messagebox, http://code.google.com/p/go-wiki/wiki/WindowsDLLs:
package main import(
"fmt"
"syscall"
"unsafe") func abort(funcname string, err error){
panic(fmt.Sprintf("%s failed: %v", funcname, err))}var(
kernel32, _ = syscall.LoadLibrary("kernel32.dll")
getModuleHandle, _ = syscall.GetProcAddress(kernel32,"GetModuleHandleW") user32, _ = syscall.LoadLibrary("user32.dll")
messageBox, _ = syscall.GetProcAddress(user32,"MessageBoxW"))const(
MB_OK =0x00000000
MB_OKCANCEL =0x00000001
MB_ABORTRETRYIGNORE =0x00000002
MB_YESNOCANCEL =0x00000003
MB_YESNO =0x00000004
MB_RETRYCANCEL =0x00000005
MB_CANCELTRYCONTINUE =0x00000006
MB_ICONHAND =0x00000010
MB_ICONQUESTION =0x00000020
MB_ICONEXCLAMATION =0x00000030
MB_ICONASTERISK =0x00000040
MB_USERICON =0x00000080
MB_ICONWARNING = MB_ICONEXCLAMATION
MB_ICONERROR = MB_ICONHAND
MB_ICONINFORMATION = MB_ICONASTERISK
MB_ICONSTOP = MB_ICONHAND MB_DEFBUTTON1 =0x00000000
MB_DEFBUTTON2 =0x00000100
MB_DEFBUTTON3 =0x00000200
MB_DEFBUTTON4 =0x00000300) func MessageBox(caption, text string, style uintptr)(result int){
var nargs uintptr =4
ret, _, callErr := syscall.Syscall9(uintptr(messageBox),
nargs,
0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
style,
0,
0,
0,
0,
0)
if callErr !=0{
abort("Call MessageBox", callErr)
}
result =int(ret)
return} func GetModuleHandle()(handle uintptr){
var nargs uintptr =0
if ret, _, callErr := syscall.Syscall(uintptr(getModuleHandle), nargs,0,0,0); callErr !=0{
abort("Call GetModuleHandle", callErr)
}else{
handle = ret
}
return} func main(){
defer syscall.FreeLibrary(kernel32)
defer syscall.FreeLibrary(user32) fmt.Printf("Return: %d\n",MessageBox("Done Title","This test is Done.", MB_YESNOCANCEL))} func init(){
fmt.Print("Starting Up\n")}
Golang下通过syscall调用win32的dll(calling Windows DLLs from Go )的更多相关文章
- paip.java c# .net php python调用c++ c dll so windows api 总结
paip.java c# .net php python调用c++ c dll so windows api 总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来 ...
- Windows API方式直接调用C#的DLL,支持多音字转拼音、Gzip解压缩、公式计算(VBA、C++、VB、Delphi甚至java都可以)
原始链接 https://www.cnblogs.com/Charltsing/p/DllExport.html 这两年,我在VBA应用方面一直有几大痛点:1.多音字转拼音:2.64位下的GZIP解压 ...
- 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑
因客户需求,与第三方对接,调用非托管DLL,之前正常对接的程序,却总是报“内存已损坏的异常”,程序进程直接死掉,折腾到这个点(2018-05-11 00:26),终于尘埃落定,直接上程序. 之前的程序 ...
- golang调用c++的dll库文件
最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...
- C++在VS下创建、调用dll
转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...
- 在 C# 中通过 P/Invoke 调用Win32 DLL
在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 | 更新日期 : 1/13/2005 Jason Clark 下载本文的代码: NET0307.exe ( ...
- C#中可直接调用WIN32的API函数--USER32.DLL
Win32的API函数可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候直接调用Win32的API,可以很高效的实现想要的效果. using System; using System ...
- vs2010下C++调用lib或dll文件
注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1 设置工程的 ...
- C# 调用win32 DLL报错 System.BadImageFormatException
C# 调用win32 DLL报错 System.BadImageFormatException 项目右键属性->项目设计器->生成->平台->把'默认设置(任何 CPU)'改 ...
随机推荐
- [转帖]MATLAB曲线绘制及颜色类型
信号源产生的方法 来源:http://www.2cto.com/kf/201401/270494.html matlab的checkerboard说明,GOOD! 来源:http://www.chi ...
- 收集 数据库的awr数据,生成报告
该脚本只是把awr报告的内容,原封不动的 展现出来,做记录 awrreport.sql 脚本内容如下: *********************************************** ...
- Elasticsearch学习2--Elasticsearch数据类型简介
1.Elasticsearch 是 面向文档型数据库,这意味着它存储的是整个对象或者 文档,它不但会存储它们,还会为他们建立索引,这样你就可以搜索他们了.你可以在 Elasticsearch 中索引. ...
- (JAVA)从零开始之--对象输入输出流ObjectInputStream、ObjectOutputStream(对象序列化与反序列化)
对象的输入输出流 : 主要的作用是用于写入对象信息与读取对象信息. 对象信息一旦写到文件上那么对象的信息就可以做到持久化了 对象的输出流: ObjectOutputStream 对象的输入流: Ob ...
- 浅谈 trie树 及其实现
定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...
- PHP做支付宝即时到账需注意
注意:1按照人家的参数规则,规范填写参数列表:2商家信息填写正确:3然后提交走后注意此时告别了咱们的服务器,将在咱们服务器的订单信息提交到了支付宝服务器,然后支付宝服务器进行支付宝支付流程,当如果支付 ...
- xv6中存储cpu和进程信息的技巧
xv6是一个支持多处理器的Unix-like操作系统, 近日阅读源码时发现xv6在记录当前CPU和进程状态时非常tricky 首先,上代码: extern struct cpu cpus[NCPU]; ...
- Win8.1 64bit安装Genymotion模拟器
其实安装并不复杂,只要环境正常,此事并不难.但估计最坏的情况都被我撞上了,才折腾了差不多一天的 那我有哪些环境不正常呢? 破解了系统主题 Device Install Service服务未启动 下面来 ...
- Linux之Vim编辑器使用
vim文本编辑器用于建立 编辑 显示文本文件,vim没有菜单,只有命令 在windows 平台下可使用gvim进行编写 Vim三种工作模式: 常有命令: 1.INSERT插入命令 i 在光标前插入 I ...
- php基础知识【函数】(8)xml和变量函数
一.XML函数 参数类型 data --string,需要解析的数据集. parser --resource,一个指向要取得字节索引的 XML 解析器的引用. 1.创建和释放XMl解析器 ...