使用 C++ 和嵌入式单声道调用 C# DLL 时无法加载程序集系统
Posted
技术标签:
【中文标题】使用 C++ 和嵌入式单声道调用 C# DLL 时无法加载程序集系统【英文标题】:Could not load assembly System when using C++ and embedded mono to call to C# DLL 【发布时间】:2017-09-26 19:28:16 【问题描述】:我有一个 C# 示例代码,它在 Linux 上使用 xbuild
编译成 DLL,例如:
using System;
using System.IO;
using System.Collections.Generic;
// ...
namespace MySamples
public class MyExample
public static void test()
SortedSet<int> ss = new SortedSet<int>();
// main function calls for test()
我可以在命令行中使用xbuild MyExample.csproj
轻松地将示例代码编译为exe
或dll
,然后使用mono MyExample.exe
运行——一切正常,示例代码返回预期结果。
现在我想从我的 C++ 代码中调用示例代码,特别是调用 test()
函数。我为此使用单声道运行时,这是我的 C++ 代码:
#include <mono/jit/jit.h>
#include <mono/metadata/object.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/mono-config.h>
// ...
MonoDomain* domain = mono_jit_init("MyExample.dll");
MonoAssembly* assembly = mono_domain_assembly_open(domain, "MyExample.dll");
mono_config_parse("MyExample.dll.config");
// mono is not installed in default locations:
mono_set_dirs("mypath/lib/mono", "mypath/etc/mono");
MonoImage* image = mono_assembly_get_image(assembly);
MonoClass* klass = mono_class_from_name(image, "MySamples", "MyExample");
MonoObject* object = mono_object_new(domain, klass);
mono_runtime_object_init(object);
// call test()
MonoMethodDesc* mdesc = mono_method_desc_new(":test()", false);
MonoMethod* method = mono_method_desc_search_in_class(mdesc, klass);
mono_runtime_invoke(method, object, NULL, NULL);
// shutdown the runtime
mono_jit_cleanup (domain);
C++ 代码在运行时返回错误类型:
未处理的异常: System.IO.FileNotFoundException:无法加载文件或程序集“系统,版本 = 4.0.0.0,文化 = 中性,PublicKeyToken = ...”或其依赖项之一。 ...
因为我知道如果我通过命令行使用mono
运行相同的代码并且它可以工作,我觉得我的 C++ 代码以及我如何设置单声道运行时存在问题。我通过添加 mono_set_dirs
修复了一堆其他错误,因为我的 Mono 没有安装到默认目录中(它是从源代码构建的)。
我在 Ubuntu 16.04 上,如果重要的话,mono 是从源代码构建的,CMake 用于编译我的 C++ 代码,MyExample.dll.config
内容:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
*.csproj
文件以下列方式包含System
:
<Reference Include="System" />
再一次,当我从命令行(不是来自 C++ 项目)使用 mono
并使用现在的 C# 设置时,我能够运行 test()
。
还有一件奇怪的事情:如果我将SortedSet<int>
替换为List<int>
,它运行时不会抛出任何错误。怎么可能? -they belong to the same namespace。我检查了其他类型,在初始化它们中的大多数时,都会抛出异常。
有什么想法吗?我一直在检查mono embedded docs 试图找出我的设置可能有什么问题,但这是我所能达到的。我是 C#、单声道运行时和嵌入式单声道的初学者。
【问题讨论】:
可能相关:***.com/questions/8873091/… - 你检查过你的单声道编译器标志了吗?特别是-sdk=4
@JoshE 我使用xbuild
,它使用csc
。但我可以看到它链接到mscorlib.dll
作为参考。正如我在问题中所说,我觉得问题出在 C++ 代码上,而不是 C#。
我明白 - 我是 b/c System.Collections.Generic
的原因是可能缺少的参考;错误消息“覆盖”了这一点,顺便提到了or one of its' dependencies
。你的 csproj 没有引用 System.Collections.Generic,我也注意到了。它可能在 CLI 中工作,因为幸运/DLL 恰好可用于 proc
@JoshE 据我了解,System.Collections.Generic
是System.dll
中的命名空间,因此我不必将其包含在csproj
中。告诉我,如果我绞尽脑汁。当我查看不同版本(4.0、4.5、4.6.1、...)的单声道 DLL 时,我也看不到 System.Collections.Generic.dll
。这意味着它实际上找不到非常确定的版本的System.dll
。
您正在寻找System.Collections.DLL
,其中包含System.Collections.Generic
。你看到那个 DLL 了吗?
【参考方案1】:
问题是如此的微不足道——我在我的 C++ 代码中弄乱了 mono lib 路径。显然,您需要提供前缀,而不是完整路径。所以,就我而言,我不得不使用:
mono_set_dirs("mypath/lib", "mypath/etc");
最后不使用mono
。
【讨论】:
以上是关于使用 C++ 和嵌入式单声道调用 C# DLL 时无法加载程序集系统的主要内容,如果未能解决你的问题,请参考以下文章