英文:
Go Fails to Find Procedure in DLL
问题
为什么Go无法在dll中找到指定的过程?
我有一个为Windows x86编译的my.dll
库(操作系统是Windows 7 x64;但我正在使用Go x86二进制文件 - 使用LiteIDE - 并且C#代码也明确编译为x86架构)。我从C#中使用它,它可以正常工作:
[DllImport("my.dll", EntryPoint = "my_function")]
public static extern double my_function(double x);
但是当我尝试从Go中使用它(这里我只是尝试找到它):
var (
dllMine = syscall.NewLazyDLL("my.dll")
my_function = dllMine.NewProc("my_function")
)
func main() {
err := my_function.Find()
if err != nil {
fmt.Println(err)
return
}
//...
}
它显示Failed to find my_function procedure in my.dll: The specified procedure could not be found.
。my.dll
文件与生成的.exe
文件位于同一目录下。入口点名称("my_function"
)确实存在,因为在C#中导入时可以正常工作,并且不会显示Failed to load my.dll: The specified module could not be found.
。
实际的情况是:我尝试调用的库是swedll32.dll
,它是瑞士星历的核心库(可以在这里下载 - GNU),为了测试这种情况,要调用的函数是swe_julday
,具有以下签名:
double swe_julday(
int year, int month, int day, double hour,
int gregflag); /* Gregorian calendar: 1, Julian calendar: 0 */
另一件事是我的GOROOT
环境参数实际上是一个NTFS联接点(因此我可以在x86和x64版本之间切换) - 但我不认为这是相关的,因为输出的.exe
应用程序可以正常生成(只是为了坦白我所有的罪行!)。
英文:
Why Go fails to find the specified procedure in dll?
I have a my.dll
library compiled for Windows x86 (The OS is Windows 7 x64; but I am using Go x86 binary - with LiteIDE - and the C# code is also explicitly compiled for x86 architecture). And I use it from C# and it works:
[DllImport("my.dll", EntryPoint = "my_function")]
public static extern double my_function(double x);
But when I try to use it (here I am trying just to find it) from Go by:
var (
dllMine = syscall.NewLazyDLL("my.dll")
my_function = dllMine.NewProc("my_function")
)
func main() {
err := my_function.Find()
if err != nil {
fmt.Println(err)
return
}
//...
}
It says Failed to find my_function procedure in my.dll: The specified procedure could not be found.
. The my.dll
file resides at the same directory with the generated .exe
file. The entry point name ("my_function"
) does exists because it's working fine when is imported in C# and it does not say Failed to load my.dll: The specified module could not be found.
.
Actual pieces: The library I am trying to call is swedll32.dll
which is the core library of Swiss Ephemeris (can be downloaded here - GNU) and just for testing this scenario the function to be called is swe_julday
; for reproducing the error, with this signature:
double swe_julday(
int year, int month, int day, double hour,
int gregflag); /* Gregorian calendar: 1, Julian calendar: 0 */
Another thing is my GOROOT
environment parameter is actually a NTFS junction point (so I can switch between x86 and x64 versions) - but I do not think it's relevant, because the output .exe
app is being generated without any problem (just for the sake of confessing all my sins!).
答案1
得分: 4
我已经从http://www.astro.com/ftp/swisseph/sweph.zip下载了你的dll文件,以查看其中是否包含swe_julday函数:
C:\foo>dumpbin /exports swedll32.dll | find "swe_julday"
74 49 0000C440 _swe_julday@24
75 4A 0000D4A0 _swe_julday_d@24
但我没有在其中看到swe_julday函数。相反,我看到了_swe_julday@24函数。所以如果我将你的程序更改为:
C:\foo>type foo.go
package main
import (
"syscall"
"fmt"
)
var (
dllMine = syscall.NewLazyDLL("swedll32.dll")
my_function = dllMine.NewProc("_swe_julday@24")
)
func main() {
err := my_function.Find()
if err != nil {
fmt.Println(err)
return
}
//...
}
它将无错误运行:
C:\foo>go run foo.go
C:\foo>
英文:
I have downloaded your dll from http://www.astro.com/ftp/swisseph/sweph.zip to see if swe_julday function is in there:
C:\foo>dumpbin /exports swedll32.dll | find "swe_julday"
74 49 0000C440 _swe_julday@24
75 4A 0000D4A0 _swe_julday_d@24
And I don't see swe_julday function in there. Instead I see _swe_julday@24 function. So if I change your program to:
C:\foo>type foo.go
package main
import (
"syscall"
"fmt"
)
var (
dllMine = syscall.NewLazyDLL("swedll32.dll")
my_function = dllMine.NewProc("_swe_julday@24")
)
func main() {
err := my_function.Find()
if err != nil {
fmt.Println(err)
return
}
//...
}
it runs without any errors:
C:\foo>go run foo.go
C:\foo>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论