如何在C/C++中使用Mono(转)

下载安装Mono

进入 Mono下载页面 下载 Mono for Window 64-bit

安装完成后,可以发现Mono根目录位于C:\Program Files\Mono

项目配置 和 VS属性表

项目配置

为了能够访问 Mono的头文件和库文件,我们需要将其添加到VC++ Directories选项下的Include DirectoriesLibrary Directories中。
这里使用了自定义的属性值,可以阅读下一小节 VS属性表 设置对应的值。
image

image

VS属性表

在VS中,我们可以通过View > Property Manager 或者 View > Other Windows > Property Manager 打开属性管理窗口。

右键解决方案,可以添加新的或者已有的属性表。属性表可以存储用户定义的变量值,这样在创建新的项目时,用户可以添加之前的属性表来避免重复操作。
image

右键点击属性表,然后点击Property,我们可以修改属性表里面的用户宏(User Macros)。这里我们分别设置

Mono_RootPath = C:\Program Files\Mono
Mono_IncludePath = $(Mono_RootPath)\include\mono-2.0
Mono_LibPath = $(Mono_RootPath)\lib

image

image

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros">
    <Mono_RootPath>C:\Program Files\Mono</Mono_RootPath>
    <Mono_LibPath>$(Mono_RootPath)\lib</Mono_LibPath>
    <Mono_IncludePath>$(Mono_RootPath)\include\mono-2.0</Mono_IncludePath>
  </PropertyGroup>
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup>
    <BuildMacro Include="Mono_RootPath">
      <Value>$(Mono_RootPath)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="Mono_LibPath">
      <Value>$(Mono_LibPath)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
    <BuildMacro Include="Mono_IncludePath">
      <Value>$(Mono_IncludePath)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>
  </ItemGroup>
</Project>

项目内容

代码清单

using System;

public class Dog
{
    static public void Type()
    {
        Console.WriteLine("a Dog!");
    }
    public void Bark()
    {
        Console.WriteLine("bark!");
    }
    public void Bark(int times)
    {
        for (var i = 0; i < times; ++i )
            Console.WriteLine("bark!");
    }
}
// Main.cpp
#include <windows.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <cstdlib>
#include <string>
#include <iostream>
#pragma comment(lib, "mono-2.0-sgen.lib")

int main(int argc, char* argv[])
{
#pragma region Load and compile the script
	std::string scriptPath(R"(D:\Code\Mono\Dog.cs)");
	std::string command = "csc " + scriptPath + " -target:library";

	//Compile the script
	system(command.c_str());
#pragma endregion

#pragma region Init mono runtime
	mono_set_dirs("C:\\Program Files\\Mono\\lib",
		"C:\\Program Files\\Mono\\etc");

	//Init a domain
	MonoDomain* domain;
	domain = mono_jit_init("MonoScriptTry");
	if (!domain)
	{
		std::cout << "mono_jit_init failed" << std::endl;
		system("pause");
		return 1;
	}

	//Open a assembly in the domain
	MonoAssembly* assembly;
	const char* assemblyPath = "D:\\Code\\Mono\\Dog.dll";
	assembly = mono_domain_assembly_open(domain, assemblyPath);
	if (!assembly)
	{
		std::cout << "mono_domain_assembly_open failed" << std::endl;
		system("pause");
		return 1;
	}

	//Get a image from the assembly
	MonoImage* image;
	image = mono_assembly_get_image(assembly);
	if (!image)
	{
		std::cout << "mono_assembly_get_image failed" << std::endl;
		system("pause");
		return 1;
	}
#pragma endregion

#pragma region Run a static method
	{
		//Build a method description object
		MonoMethodDesc* TypeMethodDesc;
		const char* TypeMethodDescStr = "Dog:Type()";
		TypeMethodDesc = mono_method_desc_new(TypeMethodDescStr, NULL);
		if (!TypeMethodDesc)
		{
			std::cout << "mono_method_desc_new failed" << std::endl;
			system("pause");
			return 1;
		}

		//Search the method in the image
		MonoMethod* method;
		method = mono_method_desc_search_in_image(TypeMethodDesc, image);
		if (!method)
		{
			std::cout << "mono_method_desc_search_in_image failed" << std::endl;
			system("pause");
			return 1;
		}

		//run the method
		std::cout << "Running the static method: " << TypeMethodDescStr << std::endl;
		mono_runtime_invoke(method, nullptr, nullptr, nullptr);
	}
#pragma endregion

#pragma region Run a normal method
	{
		//Get the class
		MonoClass* dogclass;
		dogclass = mono_class_from_name(image, "", "Dog");
		if (!dogclass)
		{
			std::cout << "mono_class_from_name failed" << std::endl;
			system("pause");
			return 1;
		}

		//Create a instance of the class
		MonoObject* dogA;
		dogA = mono_object_new(domain, dogclass);
		if (!dogclass)
		{
			std::cout << "mono_object_new failed" << std::endl;
			system("pause");
			return 1;
		}

		//Call its default constructor
		mono_runtime_object_init(dogA);

		//Build a method description object
		MonoObject* result;
		MonoMethodDesc* BarkMethodDesc;
		const char* BarkMethodDescStr = "Dog:Bark(int)";
		BarkMethodDesc = mono_method_desc_new(BarkMethodDescStr, NULL);
		if (!BarkMethodDesc)
		{
			std::cout << "mono_method_desc_new failed" << std::endl;
			system("pause");
			return 1;
		}

		//Search the method in the image
		MonoMethod* method;
		method = mono_method_desc_search_in_image(BarkMethodDesc, image);
		if (!method)
		{
			std::cout << "mono_method_desc_search_in_image failed" << std::endl;
			system("pause");
			return 1;
		}

		//Set the arguments for the method
		void* args[1];
		int barkTimes = 3;
		args[0] = &barkTimes;

		//Run the method
		std::cout << "Running the method: " << BarkMethodDescStr << std::endl;
		mono_runtime_invoke(method, dogA, args, nullptr);
	}
#pragma endregion

	system("pause");
	return 0;
}


参考

An example of embedding Mono runtime in C/C++.

Mono官方文档:嵌入

posted @ 2026-03-19 18:53  dewxin  阅读(1)  评论(0)    收藏  举报