英文:
go LoadDLL with dependencies not in System or System32
问题
我正在尝试在Windows上加载一个GO库:
citect, err := syscall.LoadDLL("C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)CtApi.dll")
问题是该库还有其他依赖项在同一目录中。结果是出现错误"找不到指定的模块"。我相当确定这是因为其他DLL中存在未满足的依赖关系导致的。
是否有一种方法可以通过syscall强制指定DLL搜索路径?
更新
我认为我遇到的问题是因为我指定了LOAD_LIBRARY_SEARCH_USER_DIRS,但我尝试加载的库还需要标准搜索路径。我添加了LOAD_LIBRARY_SEARCH_DEFAULT_DIRS,现在它给我一个有意义的句柄。
func main() {
fmt.Println("hello")
dllPath := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (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: %d\n", r1)
if r1 == 0 {
panic(err)
}
h, err := windows.LoadLibraryEx("CtApi.dll", 0, 0)
if err != nil {
panic(err)
}
fmt.Printf("library: %v\n", h)
}
英文:
I am trying to load a library from GO on windows as:
citect, err := syscall.LoadDLL("C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)CtApi.dll")
The problem is that this library has dependencies also in that directory. The result is an error "The specified module could not be found." I am pretty sure it's failing because of unmet dependencies in other DLLs.
Is there some way from syscall to force the DLL search path?
UPDATE
I think the issue I was having was because I was specifying LOAD_LIBRARY_SEARCH_USER_DIRS but the library I am trying to load needs the standard search path as well. I added LOAD_LIBRARY_SEARCH_DEFAULT_DIRS and now it gives me a Handle that makes sense.
func main() {
fmt.Println("hello")
dllPath := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (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: %d\n", r1)
if r1 == 0 {
panic(err)
}
h, err := windows.LoadLibraryEx("CtApi.dll", 0, 0)
if err != nil {
panic(err)
}
fmt.Printf("library: %v\n", h)
}
答案1
得分: 2
尝试使用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 SCADA\\Bin\\Bin (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,
}
// 使用dll
}
请注意,LOAD_LIBRARY_SEARCH_*
标志在所有Windows版本上都不可用。请参见此处的代码注释。
英文:
Try to use LoadLibraryEx
in the golang.org/x/sys/windows
package, which supports the LOAD_LIBRARY_SEARCH_*
flags (see Search order using LOAD_LIBRARY_SEARCH flags).
package main
import (
"golang.org/x/sys/windows"
)
func main() {
name := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (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
}
Please note that the LOAD_LIBRARY_SEARCH_*
flags are not available on all windows versions. See code comments here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论