go - 导入从 Go 构建的 Dll 和运行时错误
问题描述
我有一个 Win64 Dll 文件,名称为“test.dll”。使用 MinGW64 构建它。dll里面的代码是这样的:
// GOLANG CODE
package main
import "C"
import "time"
//export TestGo
func TestGo(str *C.char)*C.char {
gostr := C.GoString(str)
println("TestGo : ", str)
time.Sleep(time.Second * 3)
gostr = "return:" + gostr
cstr := C.CString(gostr)
return cstr
}
func main() {
}
我还有另一个 Go 程序,尝试导入这个“test.dll”:
// GOLANG CODE
package main
import "C"
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
pth := "./godll/test.dll"
dll := syscall.NewLazyDLL(pth)
ptrfun := dll.NewProc("TestGo")
msg := C.CString("this is a message")
res, _, _ := ptrfun.Call(uintptr(unsafe.Pointer(msg)))
gostr := C.GoString((*C.char)(unsafe.Pointer(res)))
fmt.Println(gostr)
for {
select {}
}
}
当我运行这个程序时,我得到了这个:
TestGo : 0x1864b921f80
fatal error: unexpected signal during runtime execution
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x6bf1f528]
goroutine 1 [running, locked to thread]:
runtime.throw(0x6bf524d9, 0x2a)
I:/Soft_Install/GO/src/runtime/panic.go:1116 +0x79 fp=0xc00010ef08 sp=0xc00010eed8 pc=0x6bef2859
runtime.sigpanic()
I:/Soft_Install/GO/src/runtime/signal_windows.go:240 +0x285 fp=0xc00010ef38 sp=0xc00010ef08 pc=0x6bf040a5
runtime.memmove(0x0, 0xc00004a050, 0x1)
I:/Soft_Install/GO/src/runtime/memmove_amd64.s:148 +0x108 fp=0xc00010ef40 sp=0xc00010ef38 pc=0x6bf1f528
runtime.heapBitsSetType(0xc00004a050, 0x50, 0x48, 0x6bf48a60)
I:/Soft_Install/GO/src/runtime/mbitmap.go:1373 +0x4cd fp=0xc00010f048 sp=0xc00010ef40 pc=0x6bed310d
runtime.mallocgc(0x50, 0x6bf48a60, 0x1, 0x6bf4c29e)
I:/Soft_Install/GO/src/runtime/malloc.go:1090 +0x5ee fp=0xc00010f0e8 sp=0xc00010f048 pc=0x6beccace
runtime.newobject(0x6bf48a60, 0x1)
I:/Soft_Install/GO/src/runtime/malloc.go:1195 +0x3f fp=0xc00010f118 sp=0xc00010f0e8 pc=0x6becd23f
time.Sleep(0xb2d05e00)
I:/Soft_Install/GO/src/runtime/time.go:182 +0x108 fp=0xc00010f158 sp=0xc00010f118 pc=0x6bf1b828
main.TestGo(0x1864b921f80, 0x0)
C:/Users/hgmmy/Desktop/GitGoCache/maquego/Test/GoDllTest/godll/dll.go:16 +0x93 fp=0xc00010f1d0 sp=0xc00010f158 pc=0x6bf2d833
main._cgoexpwrap_0fad9edfa800_TestGo(0x1864b921f80, 0x0)
_cgo_gotypes.go:73 +0x67 fp=0xc00010f208 sp=0xc00010f1d0 pc=0x6bf2d6a7
runtime.call32(0x0, 0x55e6dff3d0, 0x55e6dff540, 0x10)
I:/Soft_Install/GO/src/runtime/asm_amd64.s:540 +0x45 fp=0xc00010f238 sp=0xc00010f208 pc=0x6bf1cc25
runtime.cgocallbackg1(0x0)
I:/Soft_Install/GO/src/runtime/cgocall.go:332 +0x1b8 fp=0xc00010f2d0 sp=0xc00010f238 pc=0x6bec3558
runtime.cgocallbackg(0x0)
I:/Soft_Install/GO/src/runtime/cgocall.go:207 +0xe5 fp=0xc00010f338 sp=0xc00010f2d0 pc=0x6bec32e5
runtime: unexpected return pc for runtime.cgocallback_gofunc called from 0x78dca7
stack: frame={sp:0xc00010f338, fp:0xc00010f358} stack=[0xc000100000,0xc000110000)
000000c00010f238: 0000000000000000 00000055e6dff3d0
000000c00010f248: 00000055e6dff540 0000000000000010
000000c00010f258: 000000006befcd0f <runtime.exitsyscallfast+207> 000000c000020000
000000c00010f268: 0000000000000000 0000000000000000
000000c00010f278: 0202010000000000 0000000000000000
000000c00010f288: 0000000000000000 000000c00010f2c0
000000c00010f298: 000000c000034000 000000c00010f27d
000000c00010f2a8: 000000006bf539d0 0000000000000000
000000c00010f2b8: 0000000000000000 000000c00010f328
000000c00010f2c8: 000000006bec32e5 <runtime.cgocallbackg+229> 0000000000000000
000000c00010f2d8: 0000000000000000 0000000000724775
000000c00010f2e8: 000000006bf2d9a0 0000000000000001
000000c00010f2f8: 000000c00010f3e8 000000006bf2d9a0
000000c00010f308: 0000000000000000 0000000000000000
000000c00010f318: 000000c00010f360 000000c000034000
000000c00010f328: 00000055e6dff390 000000006bf1e3d2 <runtime.cgocallback_gofunc+178>
000000c00010f338: <0000000000000000 00000000008a0020
000000c00010f348: 000000c00010f360 !000000000078dca7
000000c00010f358: >00000000007247a9 000000000078f880
000000c00010f368: 00000000008a02e0 00000000008a0020
000000c00010f378: 000000c000034000 00000000008a0020
000000c00010f388: 000000c00010f3c8 000000000078ac1c
000000c00010f398: 000000000078f880 00000000008a02e0
000000c00010f3a8: 0000000000000000 0100000000000000
000000c00010f3b8: 00000000008a0020 0000000000832f90
000000c00010f3c8: 000000c00010fde8 000000000079e9fb
000000c00010f3d8: 000000006bf2d9a0 0000000000000001
000000c00010f3e8: 000001864b921f80 0000000000000000
000000c00010f3f8: 0000000000000000 0000000000000000
000000c00010f408: 0000000000000000 0000000000000000
000000c00010f418: 0000000000000000 0000000000000000
000000c00010f428: 0000000000000000 0000000000000000
000000c00010f438: 0000000000000000 0000000000000000
000000c00010f448: 0000000000000000 0000000000000000
runtime.cgocallback_gofunc(0x7247a9, 0x78f880, 0x8a02e0, 0x8a0020)
I:/Soft_Install/GO/src/runtime/asm_amd64.s:794 +0xb2 fp=0xc00010f358 sp=0xc00010f338 pc=0x6bf1e3d2
goroutine 1 [runnable, locked to thread]:
syscall.LoadDLL(0x6bf4d1ab, 0xc, 0x1c00004e078, 0x6bf6282d, 0x1c00004e000)
I:/Soft_Install/GO/src/syscall/dll_windows.go:92 +0x30d
syscall.(*LazyDLL).Load(0x1c000004060, 0x0, 0x0)
I:/Soft_Install/GO/src/syscall/dll_windows.go:245 +0xc8
syscall.(*LazyProc).Find(0x1c00004c2a0, 0x0, 0x0)
I:/Soft_Install/GO/src/syscall/dll_windows.go:300 +0xbf
syscall.(*LazyProc).mustFind(...)
I:/Soft_Install/GO/src/syscall/dll_windows.go:318
syscall.(*LazyProc).Addr(...)
I:/Soft_Install/GO/src/syscall/dll_windows.go:327
syscall.GetStdHandle(0xfffffffffffffff6, 0x1c00003bee8, 0x6bf280f8, 0x6bf461e0)
I:/Soft_Install/GO/src/syscall/zsyscall_windows.go:366 +0x3e
syscall.getStdHandle(0xfffffffffffffff6, 0x6bf4e818)
I:/Soft_Install/GO/src/syscall/syscall_windows.go:467 +0x32
syscall.init()
I:/Soft_Install/GO/src/syscall/syscall_windows.go:461 +0x129a
但!!! 我可以用 Python 调用 dll:(Python 代码)
# PYTHON CODE
from ctypes import *
dll=CDLL("test.dll")
dll.TestGo.restype = c_char_p
msg=create_string_buffer("this is a message".encode())
res = dll.TestGo(msg)
print(string_at(res).decode())
Python 返回:
TestGo : 0x259bd3aad90
return:this is a message
它返回正确的答案。
那么,为什么我不能从 Go 调用这个 Dll 函数......?
解决方案
推荐阅读
- java - 如何从位图中获取 rgb 值?
- shell - 脚本中的 Sed 命令以查找字符串(如果存在),否则附加新字符串
- python - 用python翻译数据框列
- sas - 如何使用 proc mianalyze 预测测试集
- python - 根据列值在数据框中添加空白单元格(excel:插入单元格并右移)
- smalltalk - 我将如何使用 TableLayout 以不同的方式处理某些特定的子变形?
- javascript - 如何使用 Auth0 Lock 从响应对象中获取用户名?
- c# - 委托 BadStartNameChar 异常
- ios - 如果 URL 无法打开,则显示警报
- python - Lambda 函数不会从 MySQL 返回所有行