【问题标题】:Can I build a Go program while statically linking some DLLs with it?我可以在静态链接一些 DLL 的同时构建 Go 程序吗?
【发布时间】:2019-01-22 03:22:00
【问题描述】:

如果您在慢速硬盘上运行带有 Windows DLL 依赖项的 go 应用程序,有时会出现 Windows 加载这些 dll 的时间过长。

如果您将 Go 应用程序放入 Windows 服务中,您会遇到严重的问题。

特别是在慢速硬盘上,这会导致 windows 服务超时,服务将无法启动。

是否有可能以某种方式将这些 DLL 静态链接到 go 应用程序?

加载 DLL 后一切正常,但需要两次尝试才能使服务运行。

但是在第一次失败后,Windows 不会再尝试启动服务,所以我必须自己手动启动服务。

有人有想法吗?

【问题讨论】:

  • 作为一种解决方法,您可以在注册服务时延长启动超时时间吗?
  • 是的,这将是一种解决方法。但是该服务在许多客户机器上运行,我不知道它的潜在副作用:/ 据我所知,您可以在全局范围内而不是针对特定服务进行编辑
  • 不过,在超时之前无法加载一些 DLL 似乎有点令人惊讶。有没有办法让我们重现这个?
  • 我们在这里讨论的时间范围是什么?您确定问题不在其他地方(例如,您的可执行文件中的故障 - 它也是从磁盘 BTW 加载的,或者在加载自定义 .dll 时)?我不知道您是如何构建可执行文件的,但请检查msdn.microsoft.com/en-us/library/yx9zd12s.aspx(该选项只会在第一次需要时加载 .dll 而不是程序启动)。
  • 复制:在服务包装器中使用github.com/shirou/gopsutilgithub.com/kardianos/service 如果我从我的源中删除此存储库,该服务将 100% 工作。如果您滚动浏览 gopsutil 源代码,您会发现许多 dll 导入。

标签: windows go dll dllimport static-linking


【解决方案1】:

简短的回答是“否”:“DLL”代表“动态链接库”,不可能静态链接 DLL。

基本上你有两条路可以走,我会说:

  • 调试问题。

    Windows 服务启动的默认超时 为 30000 毫秒;这是很多,所以我倾向于认为 你的问题是它没有加载 DLL 或者至少没有加载 定位并将它们链接起来。

    通常的方法是两管齐下:

    • 隔离可能的情况。首先,把你的服务变成 一个简单的(比如控制台)程序,看看它是如何启动的 与冷缓存。如果行为持续存在,它会更简单 比服务调试。

    • 研究您的某些 DLL 是否会做一些愚蠢的事情 就像在他们的入口点函数中执行网络请求一样 (俗称“DllMain”)。

      如果您使用 LoadLibrary[Ex] 加载 DLL, 在这些调用中调用它们的入口点。

      考虑到这一点,尝试向您的 DLL 初始化代码。

    如果一切都失败了,试试 Sysinternals 的 procmon 或类似的工具。

  • 获取/生成这些库的静态版本——然后您将 能够静态链接它们。

    但请注意,如果问题实际上是需要处理的 随着这些库的初始化,静态链接它们 不会给你买任何东西——也就是说,它们已经链接起来很慢。


我还要注意,如果我在黑暗中的拍摄是正确的, 并且一个或多个你的库试图访问一些网络 资源,解决问题的简单方法可能是实施 为您的服务提供适当的依赖项——以便它仅启动 当它所依赖的服务启动时(例如 网络、DNS 等)。

【讨论】:

  • 我的意思是:kernel32.dll、user32.dll等。只是官方的windows dll,仅此而已。
  • 如果是,我敢打赌您的问题确实出在其他地方:这些 DLL 不会对其他人的代码造成任何问题。
【解决方案2】:

考虑使用LazyDll 来加速您的代码。

【讨论】:

    猜你喜欢
    • 2017-11-26
    • 1970-01-01
    • 2021-11-21
    • 2012-02-07
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多