使用Mono从C/C ++调用C# [英] Using mono to call C# from C/C++

查看:267
本文介绍了使用Mono从C/C ++调用C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Linux上编写docx文件,因此我正在编译 Open-XML-SDK mono .我正在尝试此操作网站建议.

我该怎么做才能理解为什么我无法为构造函数获取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

解决方案

C#语言告诉我们,类Hello的构造函数为Hello(string)是一个谎言,以使C ++和Java程序员更加熟悉. /p>

但是,像Microsoft .NET CLR一样,Mono运行时也可以使用编译后的代码,而不是C#.每个实例构造函数的真实名称是.ctor,与类型名称无关,对于类型初始值设定项(也称为静态构造函数"),其真实名称为.cctor.如果搜索.ctor(string)而不是Hello(string),则应该会成功.有一些工作 示例,一旦您知道要查找的内容,就更容易找到.

C#涉及名称的其他地方是默认索引器,嵌套类型,闭包……实际上很多.在所有这些情况下,您都可以通过使用反汇编程序(.NET中的ildasm,不确定等效的Mono工具的名称)来查看元数据中存在的真实命名约定.

I need to write docx files on Linux so I'm compiling the Open-XML-SDK with mono. I'm trying to do what this website suggests.

What can I do to understand why I can't get the MonoMethod* object for the constructor, or better, get this to work?

Here are my sample programs and output:

// 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

解决方案

That the constructor of class Hello is Hello(string) is a lie told by the C# language, to make it more familiar to C++ and Java programmers.

But the Mono runtime, like the Microsoft .NET CLR, works with compiled code, not C#. The true name of every instance constructor is .ctor, independent of the type name, and .cctor for a type initializer (aka "static constructor"). If you search for .ctor(string) instead of Hello(string), you should meet with success. There are some working examples online, easier to find once you know what to look for.

Other places where C# lies about names are for default indexers, nested types, closures.... quite a few actually. In all these cases you can see the true naming convention present in the metadata by using a disassembler (ildasm in .NET, not sure about the name of the equivalent Mono tool).

这篇关于使用Mono从C/C ++调用C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆