我正在调用一个DLL函数,它接受一个回调函数,其中回调函数返回一个指向某个数据结构的指针,DLL将对数据结构执行一些操作.
package main
import (
"golang.org/x/sys/windows"
"unsafe"
)
type A struct {}
var a = &A{}
func Callback() uintptr {
ptr := uintptr(unsafe.Pointer(a))
fmt.Printf("Address: 0x%X\n", ptr)
return ptr
}
func main() {
dll := windows.MustLoadDLL("some.dll")
init := dll.MustFindProc("init")
init.Call(windows.NewCallback(Callback))
fmt.Printf("This never get prints\n")
}
Run Code Online (Sandbox Code Playgroud)
我正在运行Windows 64位机器,DLL也是64位.
$ go version
go version go1.11.4 windows/amd64
Run Code Online (Sandbox Code Playgroud)
上面的代码将打印指针的地址0xC000080018
,但是对DLL的调用将无声地失败.我没有DLL的源代码,所以我无法打印它获得的值.所以我使用IDA pro来动态调试程序,我发现Go回调函数实际上是返回32位值而不是64位值.这是Go回调例程返回DLL之前的最终代码:
main.exe:00000000004537E7 mov eax, [rcx+rdx-8]
main.exe:00000000004537EB pop qword ptr [rcx+rdx-8]
main.exe:00000000004537EF retn
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,Go正在写入返回值eax
而不是rax
,它会丢弃更高的地址,因此DLL只会获取0x80018
并导致错误.
虽然我知道它有什么问题,但我无法弄清楚如何修复它.
更新:
我已经完成了一些Go的回调实现,并找到了汇编代码src/runtime/sys_windows_amd64.s
.我注意到, …
每行右侧都有一个标签触发器.其中一些标签可能包含消息.最初只显示一个指示符图标,并隐藏消息.(我绘制溢出以进行演示,但可能还有其他方法)当显示的图标悬停时,整个标记将向左移动并显示带有按钮的消息.
现在这是问题所在.首先,我无法在纯CSS中使用可伸缩的消息长度为标记设置动画.其次,因为我为每一行使用固定高度,所以我无法为消息文本设置正确的垂直对齐属性.
我正在尝试创建一个require包装器来加载依赖项,但我发现有一件事很难让它作为原始的require函数.当路径是相对路径时,包装器无法解析为正确的路径,因为我的加载器和调用者文件不在同一个文件夹中.这是一个简化的描述.
index.js
lib/
loader.js
foo/
bar.js
baz.js
Run Code Online (Sandbox Code Playgroud)
index.js
var loader = require('./lib/loader.js'),
bar = require('./foo/bar.js');
bar(loader);
Run Code Online (Sandbox Code Playgroud)
LIB/loader.js
module.exports = function (path) {
return require(path);
};
Run Code Online (Sandbox Code Playgroud)
富/ bar.js
module.exports = function(loader) {
var baz = loader('./baz.js');
console.log(baz);
};
Run Code Online (Sandbox Code Playgroud)
富/ baz.js
module.exports = 'baz';
Run Code Online (Sandbox Code Playgroud)
显然,当执行index.js时,找不到baz.js文件.有没有办法解决到正确的文件?
我找到了一个相对的解决方案,但它没有用.