3

我正在尝试从内存中加载单声道程序集。我的问题有两个部分,第一:当我使用mono_image_open_from_datamono_assembly_load_from组合程序集依赖项时没有加载。如果我使用相同的方法手动加载程序集依赖项,它们似乎没有添加到应用程序域中。所以它不起作用。

所以我想知道是否有任何方法可以从内存中加载这些程序集。

第二:如果可以从内存中加载程序集,是否也可以mscorlib.dll从内存中加载?mono_jit_init 尝试从库路径加载它,如果它不存在于路径中,mono 将无法初始化。有没有办法从内存中加载它?

4

1 回答 1

2

如果有人在 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...");
    ...

而已!

于 2021-01-14T19:38:15.437 回答