c# - 从 C 调用 Mono exe 找不到 libc

标签 c# .net c mono

在 Ubuntu 中,我使用 Mono (v3.2.8) 和嵌入式 Mono 运行时从 C 调用 C# 可执行文件。当我从命令行(即mono testFile.exe)调用exe(.NET 4.5)时,它工作正常。但是,当我运行 C 测试程序时,它会引发 C# 异常:

libc at   at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.get_IsMacOS () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.GetSystemWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <filename unknown>:0
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x00000] in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.HttpRequestCreator.Create (System.Uri uri) [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.Create (System.String requestUriString) [0x00000] in <filename unknown>:0
  at MyClass.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0

我已将范围缩小到这一行代码:

WebRequest request = WebRequest.Create("http://www.google.com");

查看调用堆栈和 mono 源代码,我认为失败与调用 libc.so 中的 native “uname”函数(CheckOS() 函数,mcs/class/System/的第 50 行)有关系统/平台.cs):

if (uname (buf) == 0) {

我认为发生的情况是 p/Invoke 层找不到 libc.so。然而,当我在可执行文件的 Main() 函数中进行相同的调用时,它执行得很好,我很困惑为什么它在一个地方工作,但在另一个地方却不起作用。同样奇怪的是,异常消息不是 DllNotFoundException,而是这个通用的“libc”消息(尽管我已经确认,当我尝试使用伪造的 .so p/Invoke 时,我收到了相同的消息)。

我的C代码:

int main(int argc,const char* argv[]) {
    MonoDomain* domain=mono_jit_init("testFile.exe");
    MonoAssembly* assembly=mono_domain_assembly_open(domain,"testFile.exe");
    MonoImage* image=mono_assembly_get_image(assembly);

    const char* args[1];
    args[0]="testFile.exe";
    mono_jit_exec(domain,assembly,1,(char**) args);
}

我的 C# 代码:

namespace MyClass {
    class MainClass {
        public static void Main (string[] args) {
            WebRequest request=WebRequest.Create("http://www.google.com");
        }
    }
}

gcc 编译选项为:

gcc cTest.c -I/usr/include/mono-2.0 -DREENTRANT -lmono-2.0 -lm -lrt -ldl -lpthread

单声道编译选项是:

dmcs -out:testFile.exe -platform:anycpu -sdk:4.5 -target:exe -unsafe+ -main:MyClass.MainClass -reference:System,System.Configuration,System.Data,System.ServiceModel,System.Web,System.Xml *.cs

更新: 我使用MONO_LOG_LEVEL和MONO_LOG_MASK跟踪.so搜索序列,发现成功调用的序列与不成功调用的序列完全不同。所以它正在寻找,只是不是很好。然后,我将 libc.so.6 复制到当前目录,重命名为 libc.so,然后将 LD_LIBRARY_PATH 设置为同一位置。这给了我成功。我现在让我的 Linux 专家研究如何使这个解决方案更加“正确”,但至少我有一个正在运行的程序。 This可能与我的问题相同(尽管该解决方案对我不起作用)。

最佳答案

问题是您缺少 dll 映射 (mono_config_parse)。以下内容将适用于 Mono 3.x 和 4.x 嵌入,并避免出现 libc 错误。

#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
#include <stdlib.h>

int 
main(int argc, char* argv[]) {
    MonoDomain *domain;
    const char *file;
    int retval;

    mono_config_parse (NULL);
    domain = mono_jit_init ("textFile.exe");
    MonoAssembly *assembly;
    assembly = mono_domain_assembly_open (domain, "testFile.exe");
    mono_jit_exec (domain, assembly, argc, argv);
    retval = mono_environment_exitcode_get ();      
    mono_jit_cleanup (domain);
    return retval;
}

运行时的某些功能(例如Dll重映射)依赖于配置文件,要加载配置文件,只需添加:

mono_config_parse (NULL);

这将加载 Mono 配置文件(通常是/etc/mono/config)。

http://www.mono-project.com/docs/advanced/embedding

仅供引用:在 Ubuntu 15.04 上,我使用的是:

gcc main.c `pkg-config --cflags --libs mono-2`

当然,您可以更新它以获取 mono-sgen 与 boehm jit。

在 OS-X 上:

gcc main.c -m32 -framework Foundation -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk \
 -lmonosgen-2.0 \
 -I/Library/Frameworks/Mono.framework/Headers/mono-2.0 \
 -L/Library/Frameworks/Mono.framework/Libraries

关于c# - 从 C 调用 Mono exe 找不到 libc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31295752/

相关文章:

java - Java 对 WPF 的回答是什么?

c# - 从 Windows 桌面应用程序发送电子邮件错误报告

c - 如何禁用 C 编程中的四舍五入

C语言,文件结构

c - 使用 fcntl.h close 无法正确关闭文件

时间:2019-03-08 标签:c#interopmarshallinganddisposing

c# - 直接打印时 GhostScript 挂起

c# - 将图像文件保存到sql Server并将字节数组转换为图像

javascript - 使用 axios 从 vue 上传 XML 文件到 asp .net core

c# - 获取 Twain 1.x 已安装驱动程序列表