php小编百草在这里为大家介绍一种常见的错误提示:“go LoadDLL 其依赖项不在 System 或 System32 中”。当我们在使用go语言编写程序时,有时会遇到这个错误提示,表示我们的程序在加载动态链接库时找不到依赖项所在的路径。这个问题可能会导致程序无法正常运行,因此我们需要解决这个问题才能继续进行开发工作。在本文中,我们将详细介绍如何解决这个错误,并提供一些常见的解决方法和技巧。
问题内容
我正在尝试从 windows 上的 go 加载库,如下所示:
citect, err := syscall.loaddll("c:program files (x86)aveva plant scadabinbin (x64)ctapi.dll")
问题是该库在该目录中也有依赖项。结果是错误“找不到指定的模块”。我很确定它失败是因为其他 dll 中未满足的依赖关系。
系统调用是否有某种方法可以强制 dll 搜索路径?
更新
我认为我遇到的问题是因为我指定了 load_library_search_user_dirs 但我尝试加载的库也需要标准搜索路径。我添加了 load_library_search_default_dirs,现在它给了我一个有意义的句柄。
func main() {
fmt.Println("hello")
dllPath := "C:Program Files (x86)AVEVA Plant SCADABinBin (x64)"
kernel, _ := windows.LoadDLL("kernel32.dll")
defer kernel.Release()
sdd, err := kernel.FindProc("SetDefaultDllDirectories")
if err != nil {
panic(err)
}
r1, _, err := sdd.Call(windows.LOAD_LIBRARY_SEARCH_SYSTEM32)
if r1 == 0 {
panic(err)
}
addd, err := kernel.FindProc("AddDllDirectory")
if err != nil {
panic(err)
}
chars := StringToWideCharPtr(dllPath)
r1, _, err = addd.Call(uintptr(unsafe.Pointer(chars)))
fmt.Printf("result of add dll directory: %dn", r1)
if r1 == 0 {
panic(err)
}
h, err := windows.LoadLibraryEx("CtApi.dll", 0, 0)
if err != nil {
panic(err)
}
fmt.Printf("library: %vn", h)
}
解决方法
尝试在golang.org/x/sys/windows
包中使用loadlibraryex
,它支持load_library_search_*
标志(参见使用 load_library_search 标志的搜索顺序)。
package main
import (
"golang.org/x/sys/windows"
)
func main() {
name := "C:Program Files (x86)AVEVA Plant SCADABinBin (x64)CtApi.dll"
h, err := windows.LoadLibraryEx(name, 0, windows.LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
if err != nil {
panic(err)
}
dll := &windows.DLL{
Name: name,
Handle: h,
}
// use the dll
}
请注意,load_library_search_*
标志并非在所有 windows 版本上都可用。请参阅此处的代码注释。