使用Mono从C/C++调用C#

4

我需要在Linux上编写docx文件,因此正在使用mono编译Open-XML-SDK。我尝试按照this website的建议操作。

我该怎么做才能了解为什么无法获取构造函数的MonoMethod*对象,或者更好地让它正常工作?

以下是我的示例程序和输出:

// hello.cs
using System;
namespace HelloWorld
{
    class Hello 
    {
    public Hello(string s) { _s = s; }

    public void DoSomething(string s) { _s = s; }

    public string _s;
    }
}

// hello.cpp
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

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

  MonoClass* helloClass = mono_class_from_name(image, "HelloWorld", "Hello");


  MonoMethodDesc* ctorDesc = mono_method_desc_new("HelloWorld.Hello:Hello(string)", false);
  MonoMethod* ctorMethod = mono_method_desc_search_in_class(ctorDesc, helloClass);

  printf("ctorDesc from mono_method_desc_new() is %p\n", ctorDesc);
  printf("ctorMethod from mono_method_desc_search_in_class() is %p    <----\n", ctorMethod);


  MonoMethodDesc* doDesc = mono_method_desc_new("HelloWorld.Hello:DoSomething(string)", false);
  MonoMethod* doMethod = mono_method_desc_search_in_class(doDesc, helloClass);

  printf("doDesc from mono_method_desc_new() is %p\n", doDesc);
  printf("doMethod from mono_method_desc_search_in_class() is %p\n", doMethod);


  mono_jit_cleanup(domain);
}

$ mcs /nologo /warn:4 /debug:pdbonly /o  /out:hello.dll /target:library hello.cs /reference:WindowsBase.dll
$ gcc hello.cpp -g3 `pkg-config --cflags --libs mono-2` -o hello
$ ./hello
ctorDesc from mono_method_desc_new() is 0x22b1920
ctorMethod from mono_method_desc_search_in_class() is (nil)    <----
doDesc from mono_method_desc_new() is 0x22b2590
doMethod from mono_method_desc_search_in_class() is 0x224ae38

$ uname -a
Linux U14-OOXML 3.16.0-37-generic #51~14.04.1-Ubuntu SMP Wed May 6 15:23:14 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

1
你尝试过使用真实名称.ctor,而不是C#为其C++-lite语法使用的伪名称吗? - Ben Voigt
尝试反汇编二进制文件以查找真实名称。 - Ben Voigt
已经将其转化为真正的答案。 - Ben Voigt
1个回答

3
Hello的构造函数Hello(string)是C#语言为了让C++和Java程序员更加熟悉而编造的谎言。但是,与Microsoft .NET CLR一样,Mono运行时处理的是编译代码,而不是C#代码。每个实例构造函数的真实名称都是.ctor,与类型名称无关,而类型初始化器(也称为“静态构造函数”)的名称为.cctor。如果您搜索.ctor(string)而不是Hello(string),您应该能够成功。有一些在线的工作示例更易于查找,一旦您知道要查找什么,就更容易找到。
C#在默认索引器、嵌套类型、闭包等方面也存在命名上的虚假情况......实际上有相当多的情况。在所有这些情况下,您可以使用反汇编器(.NET中的ildasm,不确定Mono工具的名称)来查看元数据中的真实命名规则。

你能帮我解决这个问题吗?我需要使用Mono从C#调用C++ dll。 - Hari Sankar v m

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接