Go无法在DLL中找到过程。

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

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>

huangapple
  • 本文由 发表于 2014年11月12日 20:03:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/26886571.html
匿名

发表评论

匿名网友

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

确定