在托管 C++ 中使用 C# DLL(命令行)

Using C# DLL in managed C++ (command line)

我已经查看了几个标题与此类似的问题,但它们要么没有谈论命令行,要么由于某种原因似乎对我不起作用。根据我的阅读,似乎我可以 "simply" 执行以下操作:

虚拟代码(C#):

using System;

public static class Foo {
    public static void Bar() {
        Console.WriteLine("o3o");
    }
}

更多伪代码(Visual C++):

#using <test.dll>

int main() {
    Foo::Bar();
    return 0;
}

C# DLL 编译使用:

csc /out:test.dll /t:library src\cs\Foo.cs

Visual C++ object 文件编译使用:

cl /Ox /clr /AI. /c src\vc\test.cpp

可执行文件编译使用:

link /out:test.exe test.obj

运行 可执行文件抛出以下异常:

Unhandled Exception: System.TypeLoadException: Could not load type 'Foo' from assembly 'test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at main()
   at mainCRTStartup()

我有一种强烈的感觉,我应该在 link 阶段也引用 DLL,但是我找不到 link 类似于 GCC [=] 的 DLL 的任何选项18=] 选项。尝试将 DLL 与 .obj 一起传递给 link 导致它告诉我不支持 linking 程序集。不过,有趣的是,如果我构建 .netmodule 而不是 DLL,即通过:

csc /out:test.dll /t:module src\cs\Foo.cs

并将 #using 指令更改为

#using <test.netmodule>

可执行文件运行无误。这感觉有点奇怪,因为我认为没有人在 .netmodules 中打包代码(无论如何 .netmodules?)。

您的所有步骤都应该有效,但一个非常简单的问题是阻止您的程序 运行。

即:你的C# DLL程序集名称是test,你的C++/CLI exe程序集同名。两人身份相同

所以在test程序集中查找Foo::Bar时,加载器首先检查程序集是否加载到AppDomain中。它是 - 它是您的 C++/CLI exe,并且您不能在同一个 AppDomain 中同时加载多个具有相同标识的程序集。你的 C# dll 甚至都没有试过。

只需更改其中一个,一切都会正常工作:

link /out:test2.exe test.obj

至于什么是 .netmodule,它是用于静态 linking 托管代码的格式,这就是为什么你设法 link 你的 C# 代码与你的 C++/CLI 代码没有问题。它大致相当于托管代码的.lib文件。
你是对的,它并不经常使用。