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

时间:2017-02-06 16:12:49

标签: c# .net dll c++-cli interop

我已经查看了一些标题就像这个问题,但他们要么不谈论命令行,要么因为某些原因似乎不适合我。从我所读到的,似乎我可以“简单地”做到以下几点:

虚拟代码(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 ++目标文件:

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()

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

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

并将#using指令更改为

#using <test.netmodule>

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

1 个答案:

答案 0 :(得分:3)

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

即:您的C#DLL程序集名称为test,并且您的C ++ / CLI exe程序集具有相同的名称。他们都有相同的身份。

因此,当在Foo::Bar程序集中查找test时,加载程序首先检查程序集是否已加载到AppDomain中。它是 - 它是您的C ++ / CLI exe,并且您无法在同一AppDomain中同时加载具有相同标识的多个程序集。你的C#dll甚至没有尝试过。

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

link /out:test2.exe test.obj

至于什么&#39; sa .netmodule,它是用于静态链接托管代码的格式,这就是为什么你设法将C#代码与C ++ / CLI代码链接起来的原因的问题。它大致相当于托管代码的.lib文件 你是对的,它不经常使用。