python - 如何在 Go 中实现 DllMain 入口点

标签 python windows go dll dllmain

我正在使用 Go 构建 DLL。

我无法实现 Windows DllMain entry point .

我的目标是当应用程序通过 LoadLibrary 加载 dll 时要调用 Test 方法,DllMain 也会被调用。然而目前该应用程序陷入了僵局,什么也没有发生。

该应用程序是非常简单的 python 代码

# App code
import ctypes
lib = ctypes.CDLL("./mydll.dll")
lib.Test()

注释:

  • 我正在使用构建

    go version go1.16.4 windows/amd64
    

    并使用构建

    go build -o mydll.dll --buildmode=c-shared
    
  • 如果我删除 DllMain,一切正常,应用程序可以成功调用 Test 方法。

  • 我知道我可以在 DllMainswitch 大小写来指定进程附加、分离等条件,我只是想保留尽可能简单。

//Go Code
package main

import "C"

import (
    "fmt"
    "os"
)

//export Test
func Test() {
    os.Create("fooFile")
}


//export DllMain
func DllMain(a uintptr, b uint32, c uintptr) int32 {
    return 1
}

func main() {
}

最佳答案

DllMain不能是 Go 函数,因为第一次调用 Go 函数会初始化 Go 运行时,这不能在 DllMain 范围内完成(有 very few things 可以在 DllMain 范围内完成)。

作为解决方法,您可以编写 DllMain在 C 中并在单独的线程中调用 Go 代码,如 this example 所示。但是您无法与 DllMain 范围内的该线程同步。 ,这样做会再次导致僵局。

还有 _cgo_wait_runtime_init_done ,但它也是异步的。

因此,如果您需要对 DLL 附件同步执行某些 Go 操作,那么您就不走运了。最好只定义一个“Init ”导出函数并在调用任何其他 API 之前调用它。

当然,Go 中加载时初始化的惯用方式是通过 init() function :

package main

import "C"

import (
    "fmt"
)

func init() {
    fmt.Println("init()")
}

//export Test
func Test() {
    fmt.Println("Test()")
}

func main() {
}

编译并运行:

go build -o mydll.dll --buildmode=c-shared
rundll32 mydll,Test

输出:

init()
Test()

关于python - 如何在 Go 中实现 DllMain 入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67969401/

相关文章:

python - 使用python etree获取xml的属性

python - 以部署用户身份通过​​结构激活 virtualenv

mysql - 无法安装 mysql 社区服务器 8.0 windows 10。我已经安装了 Server 5.7 和 Workbench 8.0 CE

json - golang 将具有数组列表的 json 转换为 golang 中的结构

go - 为什么这个 Go 程序会挂起?

google-app-engine - 我真的对导入所需的包感到困惑,但它的所有文件都被 nobuild_files 排除了

python - easy_install 在 Windows XP 中出现错误 "Not a recognized archive type"

python - 在线程内调用函数

python - 在 Windows 上为 django 开发设置 virtualenv,

c++ - 处理来自IMFSourceReader和IMFSample的图像数据