【问题标题】:embeded mono - load assemblies from memory嵌入式 mongo - 从内存中加载程序集
【发布时间】:2016-03-18 21:47:55
【问题描述】:

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

所以我想知道有没有办法从内存中加载这些程序集。

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

【问题讨论】:

    标签: c++ mono .net-assembly mono-embedding


    【解决方案1】:

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

    就是这样!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 2018-10-15
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多