【问题标题】:Where do I initialize a managed C++/CLI DLL?在哪里初始化托管 C++/CLI DLL?
【发布时间】:2010-09-25 00:23:33
【问题描述】:

在使用 C++/CLI 创建 DLL 时,或者我应该问,是否存在与 DllMain 等效的方法?

这个初始化代码不能调用什么有什么限制吗?

【问题讨论】:

    标签: dll c++-cli


    【解决方案1】:

    Dan:关于加载器锁、C++/CLI 对 CLR 的延迟加载以及混合模式二进制文件的正确初始化,我昨天刚刚在 the subject here 上发帖。

    或多或少,如果你有一个混合模式的二进制文件,当你在DllMain() 时,你不能导致任何托管代码运行。

    【讨论】:

      【解决方案2】:

      从 .NET 2.0 开始,您就有了“模块初始化程序”。见here for more information on how that solves the loader lock problemalso here

      要直接回答您的问题,this page quotes the standard 表示: “模块初始化程序中允许的代码没有限制。模块初始化程序可以运行和调用托管和非托管代码。”

      【讨论】:

      • 在应用程序访问程序集中的任何类型之前,不会调用模块初始化程序。它与 DllMain() 不同!
      • @Elmue:你错了。规范实际上说“除了从模块初始化程序直接或间接调用的方法之外,没有其他方法能够在其初始化程序完成执行之前访问模块中的类型、方法或数据。”
      • 无论规范怎么说。我试过了,我证明在您从调用代码访问 DLL 中的任何托管类、函数或类型之前,不会执行 DLL 中的任何代码。请试一试!调用 Assembly.Load()。这是 Microsoft 为提高速度而实施的一项优化。
      • @Elmue:您的测试无效。您测试的声明(“模块初始化程序在Assembly.Load() 返回之前运行”)是您自己的理论,与规范中的声明有很大不同。不知道你是不是误解了before的意思或者access the types, methods, or data的意思,但是如果你说的是Assembly.Load(),你显然不明白保证的真正含义。
      • 上述问题要求 DllMain 的等效项。如果您曾经使用 C/C++ 进行过编程,您就会知道 DlllMain 中的代码总是在 LoadLibrary() 执行时执行。托管程序集的等效项是在将 DLL 加载到进程中时始终执行的代码,例如托管 EXE 调用 Assembly.Load()。但是在这个答案中推荐的方法中并非如此。您必须首先访问程序集 DLL 中的类或函数才能调用模块初始化程序的执行。
      【解决方案3】:

      如果您在另一个托管项目(例如 ac# 应用程序)中使用 dll,则无需执行任何操作...只要您尝试访问的类是 ref 类,您就可以从任何其他托管应用程序访问它们。

      【讨论】:

      • 你没看懂问题。
      【解决方案4】:

      .Net dll 的一个巨大优势是它们避免了加载程序锁定。一个副作用是没有 DllMain。

      【讨论】:

      • 他们如何避免加载程序锁定?如果需要加载本机 dll 不会导致加载程序锁定?
      • 加载 .Net dll 可避免加载程序锁定,因为 .Net dll 不是本机 dll。加载原生 dll 会争夺加载器锁,因为原生 dll 就是原生 dll。
      • 这些 cmets 仅在使用 /clr:pure 编译时适用 只需 /clr 本身创建一个混合库,包含本机代码和托管代码,并且本机部分将具有在加载程序锁定下运行的 DllMain。
      • 这里您可以找到有关 DLLMain 和加载程序锁的更多详细信息:stackoverflow.com/questions/647310/…
      猜你喜欢
      • 1970-01-01
      • 2011-04-06
      • 2014-04-27
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 2011-02-06
      相关资源
      最近更新 更多