分享
golang调用dll
陈好 · · 15096 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
//调用方式
func WindowVersion1() {
h, err := syscall.LoadLibrary("kernel32.dll")
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
defer syscall.FreeLibrary(h)
proc, err := syscall.GetProcAddress(h, "GetVersion")
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0)
major := byte(r)
minor := uint8(r >> 8)
build := uint16(r >> 16)
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
}
func WindowVersion2() {
dll32 := syscall.NewLazyDLL("kernel32.dll")
g := dll32.NewProc("GetVersion")
r, _, _ := g.Call()
major := byte(r)
minor := uint8(r >> 8)
build := uint16(r >> 16)
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
}
//调用c++ dll
使用时将go生成的exe和c++生成的dll放在同一目录下即可.
C++:
//vs 2010,c++嵌入"::MessageBox(NULL, str, _T("..."), MB_OK);"用以调试时会引起程序崩溃.
//dlltest.h
DLL_API int __stdcall test1(LPTSTR s);
DLL_API int __stdcall test2(int *m);
//dlltest.cpp
int __stdcall test1(LPTSTR s)
{
CStringA sz(s);
cout<<sz<<endl;
return 0;
}
int __stdcall test2(int *m)
{
*m=*m*3+1;
return 123;
}
go:
func callDll1() {
dll32 := syscall.NewLazyDLL("dlltest.dll")
fmt.Println("dll name:", dll32.Name)
g := dll32.NewProc("_test1@4")
s := "1k中国fd"
r1, _, _ := g.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))))
fmt.Println("callDll1结果:", r1)
}
func callDll2() {
dll32 := syscall.NewLazyDLL("dlltest.dll")
g := dll32.NewProc("_test2@4")
var m int32
m = 10
p := &m
fmt.Printf("%#v\n", p)
r1, _, _ := g.Call(uintptr(unsafe.Pointer(p)))
fmt.Println("callDll2结果:", (int32)(r1))
//获取修改后的m值
fmt.Println(*(*int32)(unsafe.Pointer(p))) //返回31
}
dll尝试返回*string 报错原因:golang的string是struct以len判断结束,c/c++的string是以'0円'表示结束.,底层数据结果不同导致.所以使用dll传入传出数据时,要小心底层数据类型的一致性问题.
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信15096 次点击
上一篇:初识golang之函数
下一篇:[转]golang压缩加压
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
//调用方式
func WindowVersion1() {
h, err := syscall.LoadLibrary("kernel32.dll")
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
defer syscall.FreeLibrary(h)
proc, err := syscall.GetProcAddress(h, "GetVersion")
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0)
major := byte(r)
minor := uint8(r >> 8)
build := uint16(r >> 16)
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
}
func WindowVersion2() {
dll32 := syscall.NewLazyDLL("kernel32.dll")
g := dll32.NewProc("GetVersion")
r, _, _ := g.Call()
major := byte(r)
minor := uint8(r >> 8)
build := uint16(r >> 16)
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
}
//调用c++ dll
使用时将go生成的exe和c++生成的dll放在同一目录下即可.
C++:
//vs 2010,c++嵌入"::MessageBox(NULL, str, _T("..."), MB_OK);"用以调试时会引起程序崩溃.
//dlltest.h
DLL_API int __stdcall test1(LPTSTR s);
DLL_API int __stdcall test2(int *m);
//dlltest.cpp
int __stdcall test1(LPTSTR s)
{
CStringA sz(s);
cout<<sz<<endl;
return 0;
}
int __stdcall test2(int *m)
{
*m=*m*3+1;
return 123;
}
go:
func callDll1() {
dll32 := syscall.NewLazyDLL("dlltest.dll")
fmt.Println("dll name:", dll32.Name)
g := dll32.NewProc("_test1@4")
s := "1k中国fd"
r1, _, _ := g.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))))
fmt.Println("callDll1结果:", r1)
}
func callDll2() {
dll32 := syscall.NewLazyDLL("dlltest.dll")
g := dll32.NewProc("_test2@4")
var m int32
m = 10
p := &m
fmt.Printf("%#v\n", p)
r1, _, _ := g.Call(uintptr(unsafe.Pointer(p)))
fmt.Println("callDll2结果:", (int32)(r1))
//获取修改后的m值
fmt.Println(*(*int32)(unsafe.Pointer(p))) //返回31
}
dll尝试返回*string 报错原因:golang的string是struct以len判断结束,c/c++的string是以'0円'表示结束.,底层数据结果不同导致.所以使用dll传入传出数据时,要小心底层数据类型的一致性问题.