登录
首页 >  Golang >  Go问答

找不到 DLL“goDLL.dll”中名为“SampleMethod”的入口点异常未处理

来源:stackoverflow

时间:2024-03-10 17:12:25 403浏览 收藏

小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《找不到 DLL“goDLL.dll”中名为“SampleMethod”的入口点异常未处理》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

问题内容

我正在尝试从 c# 调用 golang dll,并将结果和性能与从 c# 调用 c dll 进行比较,因此我执行了以下操作:

我开始构建 c dll 并调用它 第1步:编写c代码

// cmdll.c
// compile with: -ld
int __declspec(dllexport) samplemethod(int i)
{
  return i*10;
}

第2步:编译c代码:

  • 打开 visual studio x64 本机工具命令提示符t
  • 运行命令:cl -ld cmdll.c

第 3 步:编写 c# 代码

// cm.cs
using system;
using system.runtime.interopservices;
public class mainclass
{
    [dllimport("cmdll.dll")]
    public static extern int samplemethod(int x); // function signature, must have a return type

    static void main()
    {
        console.writeline("samplemethod() returns {0}.", samplmethod(5));
    }
}

第 4 步:编译 c# 文件并将 exe 构建为:

  • 打开 visual studio x64 本机工具命令提示符t
  • 运行命令:csc -platform:x64 cm.cs

上面的事情运行顺利

我想使用 golang 做同样的事情,并遵循以下步骤:

第 1 步:编写 go 代码:

//lib.go
package main

import "c"

//export samplmethod
func samplmethod(i int) int {
    return i * 10
}

func main() {
    // need a main function to make cgo compile package as c shared library
}

第2步:构建dll文件,将上述代码编译为:

go build -ldflags="-s -w" -o lib.dll -buildmode=c-shared lib.go

我使用 -ldflags="-s -w" 来减少生成的文件大小,并且不确定应使用什么 -buildmode,因此随机选择 c-shared 而不是 c-archive 更新:我也尝试使用 go build -ldflags="-s -w" -o lib.dll -buildmode=c-archive lib.go 并得到相同的结果

第3步:编写c代码,将.dll.h文件组合起来,生成一个等效的c dll

//godll.c
#include 
#include "lib.h"
// force gcc to link in go runtime (may be a better solution than this)
goint samplmethod(goint i);

void main() {
}

第4步:将godll.c文件编译为:

gcc -shared -pthread -o godll.dll godll.c lib.dll -lwinmm -lntdll -lws2_32

第5步:构建c#代码来调用生成的dll,与上面的代码相同,但更改了dll文件名:

// cm.cs
using system;
using system.runtime.interopservices;
public class mainclass
{
    [dllimport("godll.dll")]
    public static extern int samplemethod(int x); // function signature, must have a return type

    static void main()
    {
        console.writeline("samplemethod() returns {0}.", samplmethod(5));
    }
}

第 4 步:编译 c# 文件并将 exe 构建为:

  • 打开 visual studio x64 本机工具命令提示符t
  • 运行命令:csc -platform:x64 cm.cs

然后尝试运行生成的./cm.exe文件,但出现以下错误:

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'SampleMethod' in DLL 'goDll.dll'.
   at MainClass.SampleMethod(Int32 i)
   at MainClass.Main()

正确答案


感谢@pak uula 评论,它对我的​​作用如下:

第 1 步:编写 go 代码:

// main.go
package main

import "c"
import "fmt"

//export helloworld
func helloworld() {
    fmt.printf("hello world from go\n")
}

func main() {}

// compile the code as:
// go build -ldflags="-s -w" -buildmode=c-shared -o libgo.dll main.go

第 2 步:将 c# 代码编写为:

// main.cs
using system;
using system.runtime.interopservices;
public class mainclass
{
    [dllimport("libgo.dll")]
    public static extern void helloworld(); // function signature, must have a return type

    static void main()
    {
        helloworld();
    }
}

// compile as:
// open:
// visual studio x64 native tools command prompt
// csc -platform:x64 cm.cs

第3步:编译这两个文件,首先编译go文件

第4步:运行可执行文件:

更新

  1. 转到文件:
// main.go
package main

import (
    "fmt"
)

// the import "c" should come directly after the // #include ..., i.e. no empty lines allowed,
// if there are empty lines, the compliler will read the // #include as normal comment, not as c import

/*
#include 
*/
import "c"

//export gethello
func gethello(input *c.char) *c.char {
    cstr := c.cstring(fmt.sprintf("from dll: hello, %s!\n", c.gostring(input)))
    //  c.free(unsafe.pointer(cstr))
    return cstr
}

func main() {}

// compile the code as:
// go build -ldflags="-s -w" -buildmode=c-shared -o libgo.dll main.go
  1. c# 文件:
// main.cs
using System;
using System.Text;
using System.Runtime.InteropServices;
public class MainClass
{
    [DllImport("libgo.dll", CharSet = CharSet.Unicode, 
    CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr GetHello(byte[] data);

    static string CallDll(string name) {
        IntPtr output= IntPtr.Zero;
        var a = GetHello(Encoding.UTF8.GetBytes(name));

        return "GetHello Returns: " + Marshal.PtrToStringAnsi(a);
    }

    static void Main()
    {
        Console.WriteLine(CallDll("Ahmad"));
    }
}

// compile as:
// open:
// Visual Studio x64 Native Tools Command Prompt
// csc -platform:x64 main.cs

这是一个使用字符串的示例:

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《找不到 DLL“goDLL.dll”中名为“SampleMethod”的入口点异常未处理》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>