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



我已经看了几个标题与此类似的问题,但它们要么不谈论命令行,要么由于某种原因似乎不适合我。从我读到的内容来看,我似乎可以"简单地"做以下事情:

伪代码(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 srccsFoo.cs

使用编译的Visual C++对象文件

cl /Ox /clr /AI. /c srcvctest.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()

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

csc /out:test.dll /t:module srccsFoo.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,它是用于静态链接托管代码的格式,这就是为什么您成功地将C#代码与C++/CLI代码链接而没有问题。它大致相当于托管代码的.lib文件
你说得对,它不常用。

最新更新