【问题标题】:Calling C# from C++, Reverse P/Invoke, Mixed Mode DLLs and C++/CLI从 C++、反向 P/Invoke、混合模式 DLL 和 C++/CLI 调用 C#
【发布时间】:2010-11-07 07:31:34
【问题描述】:

据我了解,我可以使用反向 P/Invoke 从 C++ 调用 C#。反向 P/Invoke 只是以下情况:

  1. 创建托管 (c#) 类。
  2. 创建一个 c++/cli(以前托管的 c++)类库项目。使用它来调用托管 c# 类(可能通过引用)。
  3. 从原生 c++ 调用 c++/cli 代码。

问题:

  1. 这是正确的吗?
  2. 在第 2 步创建的 DLL 是否称为混合模式 DLL?
  3. 就 MS 而言,C++/CLI 是否已完全取代托管 C++?
  4. 是否完全避免使用这种方法?
  5. CLR 将在什么时候创建和运行,由谁创建和运行?

提前致谢

【问题讨论】:

  • 执行此操作时,您会发现 gcroot 模板类很有用。

标签: c# c++ clr c++-cli


【解决方案1】:

使用 ilasm 2.0,您需要的代码更少,因为它可以自行生成大部分垃圾。现在只需要 .export 指令。

// unmexports.il
// Compile with : ilasm unmexports.il /dll
.assembly extern mscorlib { auto }
.assembly UnmExports {}
.module UnmExports.dll
.method public static void foo()
{
  .export [1] as foo
  ldstr "Hello from managed world"
  call void [mscorlib]System.Console::WriteLine(string)
  ret
}

【讨论】:

    【解决方案2】:

    注意,您还可以执行 C# dll 的 IL 往返并导出静态方法,其工作原理与 C++/CLI 中的导出基本相同。但是,这始终是一个后编译步骤,它确实有 some caveats(顺便说一句,你的 C++/CLI 导出也有)。

    您可以对 C# 和 C++/CLI DLL 进行 ILDASM 以查看导出是如何进行的;是这样的(来自a sample on the net):

    // unmexports.il
    // Compile with : ilasm unmexports.il /dll
    assembly extern mscorlib {}
    ..assembly UnmExports {}
    ..module UnmExports.dll
    // This flag is important
    ..corflags 0x00000002
    // This instructs the CLR to create a marshaling thunk for the unmanaged caller
    ..vtfixup [1] int32 fromunmanaged at VT_01
    ..data VT_01 = int32(0)
    ..method public static void foo()
    {
    ..vtentry 1:1
    ..export [1] as foo
    ldstr "Hello from managed world"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
    }
    

    【讨论】:

      【解决方案3】:

      以下是我所知的最佳答案:

      1. 是的
      2. 是的,它是一个混合模式的 DLL(事实上,您可以管理您的本地 C++ 项目的一个文件,并在该文件中创建此 C++/CLI 类并直接从该文件调用代码。您甚至不需要需要一个单独的 DLL 来完成此操作。
      3. C++/CLI 和托管 C++ 都代表相同的东西。唯一的区别是在 Visual Studio 2003 之前的旧版本中,它被称为托管 C++。后来,语法发生了很大变化,并被重命名为 C++/CLI。详情请查看this link
      4. 是的
      5. 每当调用托管 DLL 时都会使用 CLR。​​

      【讨论】:

      • 期望采用现有的 Win32 C++ 库并使用 C++/CLI 重新编译是否现实?
      • 不是真的... C++/CLI 是一种不同的语言,而开启 CLR 的 C++ 是不同的。如果您想在 Visual C++ 项目中打开 CLR 来执行此操作,则可以这样做,但编译时可能会出现问题。这将取决于该特定库的实现。
      • 对不起,如果这是一个愚蠢的问题,但是“C++/CLI”和“C++ 开启 CLR”有什么区别?
      • “打开 CLR 的 C++”是可以通过其属性打开 CLR 的任何 C++ 项目。您可以对一个文件、多个文件或整个项目执行此操作。 C++/CLI 项目就是这样创建的。在 VS2005 中,NewProject->VisualC++->CLR->NewProject。它默认打开 /CLR 开关,您可以直接在其中编写 C++/CLI 代码,而无需执行任何其他操作。
      猜你喜欢
      • 2011-02-11
      • 1970-01-01
      • 2010-12-13
      • 2015-03-17
      • 2015-11-02
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      相关资源
      最近更新 更多