如果有人在 2021 年仍然在寻找这个:
C# 模块:
using System;
namespace dotNetLib
{
public class API
{
static public void DoSomething()
{
Console.WriteLine("Hello From C#!");
}
}
}
C++ 单声道:
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include "module.h" // unsigned char asmData[SIZE] = { 0x4D, 0x5A, 0x90, 0x00, 0x03...
MonoDomain* domain;
MonoAssembly* assembly;
using namespace std;
#define log(fmt,...) printf(fmt "\n",__VA_ARGS__);
#define error(code) {log("exited with error %d",code);getchar();return code;}
int LoadFromFile();
int LoadFromMemory();
#define LOAD_FROM_MEMORY true
int main()
{
if (LOAD_FROM_MEMORY)
{
LoadFromMemory();
}
else
{
LoadFromFile();
}
}
int LoadFromMemory()
{
log("Initializing Domain...");
mono_set_dirs(".\\lib", "");
domain = mono_jit_init_version("myapp", "v4.0.30319");
if (!domain) error(-2);
log("Loading Image...");
MonoImageOpenStatus status;
MonoImage* image = mono_image_open_from_data((char*)asmData, sizeof asmData, false, &status);
if (!image) error(-3);
if (status != MONO_IMAGE_OK) error(-4);
log("Loading Module...");
assembly = mono_assembly_load_from(image, "", &status);
if (!assembly) error(-5);
if (status != MONO_IMAGE_OK) error(-6);
log("Getting Class...");
MonoClass* getClass = mono_class_from_name(image, "dotNetLib", "API");
if (!getClass) error(-7);
log("Getting Method...");
MonoMethod* method = mono_class_get_method_from_name(getClass, "DoSomething", 0);
if (!method) error(-8);
log("Calling Method...");
void* params[1] = { NULL };
MonoObject* returnVal = mono_runtime_invoke(method, NULL, params, NULL);
getchar();
log("Cleaning Up...");
mono_jit_cleanup(domain);
}
int LoadFromFile()
{
log("Initializing Domain...");
mono_set_dirs(".\\lib", "");
domain = mono_jit_init_version("myapp", "v4.0.30319");
if (!domain) error(6);
log("Creating Module...");
assembly = mono_domain_assembly_open(domain, "dotNetLib.dll");
if (!assembly) error(7);
MonoImage* image = mono_assembly_get_image(assembly);
if (!image) error(8);
log("Getting Class...");
MonoClass* getClass = mono_class_from_name(image, "dotNetLib", "API");
if (!getClass) error(9);
log("Getting Method...");
MonoMethod* method = mono_class_get_method_from_name(getClass, "DoSomething", 0);
if (!method) error(10);
log("Calling Method...");
void* params[1] = { NULL };
MonoObject* returnVal = mono_runtime_invoke(method, NULL, params, NULL);
getchar();
log("Cleaning Up...");
mono_jit_cleanup(domain);
}
- 如果您有依赖问题,请使用 Fody/Costura
- 如果您想从内存中加载 mscorlib.dll,
您需要对单声道源代码进行一些更改或使用虚拟文件系统,如 BoxedAppSDK 或 Turbo.Net 或 Enigma Virtual Box(免费)
要从内存中嵌入和运行mscorlib.dll,您需要将其存储为字节数组并用于mono_register_bundled_assemblies()
注册它们。
C++ 单声道:
static MonoBundledAssembly _mscorlib = { "mscorlib.dll", mscorlib, sizeof mscorlib };
int LoadFromMemory()
{
MonoBundledAssembly* bundled[1];
bundled[0] = &_mscorlib;
mono_register_bundled_assemblies((const MonoBundledAssembly**)bundled);
log("Initializing Domain...");
...
而已!