使用依赖项不在System或System32中的LoadDLL函数。

huangapple go评论110阅读模式
英文:

go LoadDLL with dependencies not in System or System32

问题

我正在尝试在Windows上加载一个GO库:

  1. 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,现在它给我一个有意义的句柄。

  1. func main() {
  2. fmt.Println("hello")
  3. dllPath := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)"
  4. kernel, _ := windows.LoadDLL("kernel32.dll")
  5. defer kernel.Release()
  6. sdd, err := kernel.FindProc("SetDefaultDllDirectories")
  7. if err != nil {
  8. panic(err)
  9. }
  10. r1, _, err := sdd.Call(windows.LOAD_LIBRARY_SEARCH_SYSTEM32)
  11. if r1 == 0 {
  12. panic(err)
  13. }
  14. addd, err := kernel.FindProc("AddDllDirectory")
  15. if err != nil {
  16. panic(err)
  17. }
  18. chars := StringToWideCharPtr(dllPath)
  19. r1, _, err = addd.Call(uintptr(unsafe.Pointer(chars)))
  20. fmt.Printf("result of add dll directory: %d\n", r1)
  21. if r1 == 0 {
  22. panic(err)
  23. }
  24. h, err := windows.LoadLibraryEx("CtApi.dll", 0, 0)
  25. if err != nil {
  26. panic(err)
  27. }
  28. fmt.Printf("library: %v\n", h)
  29. }
英文:

I am trying to load a library from GO on windows as:

  1. 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.

  1. func main() {
  2. fmt.Println("hello")
  3. dllPath := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)"
  4. kernel, _ := windows.LoadDLL("kernel32.dll")
  5. defer kernel.Release()
  6. sdd, err := kernel.FindProc("SetDefaultDllDirectories")
  7. if err != nil {
  8. panic(err)
  9. }
  10. r1, _, err := sdd.Call(windows.LOAD_LIBRARY_SEARCH_SYSTEM32)
  11. if r1 == 0 {
  12. panic(err)
  13. }
  14. addd, err := kernel.FindProc("AddDllDirectory")
  15. if err != nil {
  16. panic(err)
  17. }
  18. chars := StringToWideCharPtr(dllPath)
  19. r1, _, err = addd.Call(uintptr(unsafe.Pointer(chars)))
  20. fmt.Printf("result of add dll directory: %d\n", r1)
  21. if r1 == 0 {
  22. panic(err)
  23. }
  24. h, err := windows.LoadLibraryEx("CtApi.dll", 0, 0)
  25. if err != nil {
  26. panic(err)
  27. }
  28. fmt.Printf("library: %v\n", h)
  29. }

答案1

得分: 2

尝试使用golang.org/x/sys/windows包中的LoadLibraryEx函数,该函数支持LOAD_LIBRARY_SEARCH_*标志(参见使用LOAD_LIBRARY_SEARCH标志的搜索顺序)。

  1. package main
  2. import (
  3. "golang.org/x/sys/windows"
  4. )
  5. func main() {
  6. name := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)CtApi.dll"
  7. h, err := windows.LoadLibraryEx(name, 0, windows.LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
  8. if err != nil {
  9. panic(err)
  10. }
  11. dll := &windows.DLL{
  12. Name: name,
  13. Handle: h,
  14. }
  15. // 使用dll
  16. }

请注意,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).

  1. package main
  2. import (
  3. "golang.org/x/sys/windows"
  4. )
  5. func main() {
  6. name := "C:\\Program Files (x86)\\AVEVA Plant SCADA\\Bin\\Bin (x64)CtApi.dll"
  7. h, err := windows.LoadLibraryEx(name, 0, windows.LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
  8. if err != nil {
  9. panic(err)
  10. }
  11. dll := &windows.DLL{
  12. Name: name,
  13. Handle: h,
  14. }
  15. // use the dll
  16. }

Please note that the LOAD_LIBRARY_SEARCH_* flags are not available on all windows versions. See code comments here.

huangapple
  • 本文由 发表于 2023年4月28日 22:59:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76130844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定