Перезавантаження монодомену або збірок

Ми розробляємо гру та використовуємо C # та C ++ за допомогою mono.

монодомену

Ми використовуємо два dll; Dll1 і Dll2. Під час виконання я хочу змінити (оновити) ці dll без перезапуску гри (що триває деякий час). Ось код, який ми використовуємо:

mono_world_assembly = mono_domain_assembly_open (mono_domain, Dll1);
mono_world_image = mono_assembly_get_image (mono_world_assembly);

mono_module_assembly = mono_domain_assembly_open (mono_domain, Dll2);
mono_module_image = mono_assembly_get_image (mono_module_assembly);

Я спробував два різні шляхи, але жоден з них не був успішним. Я навіть не знаю, в чому точна помилка, оскільки я не знаю, як налагодити моно в C++.

Перший підхід полягав у використанні mono_jit_cleanup, а потім при перекомпіляції dll використовуйте наведений вище код для перезавантаження dll.

Другий підхід полягав у тому, щоб закрити збірки та зображення та знову відкрити їх при заміні DLL-файлів.

Чи припустився я помилки та/або є спосіб зробити це?

Як тільки збірка була JITed (що в основному означає, що
був використаний один із його методів), немає можливості його змінити.

Є два способи перезавантажити збірку:

1) змініть назву збірки та завантажте знову. Зауважте, що це
не буде розвантажувати/випускати типи, передбачені попередньою збіркою,
а також типи перезавантаженого вузла не сумісні з типом
Перший. Іншими словами: не робіть цього, якщо не зробили цього
зрозумів ці недоліки.

2) Використовуйте домени додатків, які можна вивантажити разом
їх збірки за проектом.

Це загальний шаблон у слові .NET, і він може бути

легко реалізується в керованому коді. Є багато
документи/зразок в Інтернеті.

Дякую за швидку відповідь.

Добре, я знаю, як це зробити на C #. Чи є спосіб творити
домен програми, використовуючи моно в C ++? Якщо є, я можу творити
мій монодомен та збірки в цьому домені програми, щоб я міг їх вивантажити.

В іншому випадку, це не допоможе мені створити домен додатка в C #, починаючи з
DLL, які я хочу змінити, заблоковані моно в C++.

Ну, насправді не має значення, хто створює домени
і завантаження вузлів. Це набагато простіше у реалізації
це в C #, а потім mono_runtime_invoke це з C++.

Звичайно, ви можете викликати все з C ++, але це буде
ймовірно в три примірники кількості коду, який слід написати.

Крім того, єдиним безпечним способом створення домену в C ++ є
mono_runtime_invoke-ing System.AppDomain.CreateDomain (), IIRC.

Ви можете використовувати mono_domain_create () та mono_domain_unload () просто чудово з
c. Насправді, я підозрюю, що це насправді
це простіше зробити з власного коду в наші дні. в основному те, що ви повинні зробити, це:

створити домен
встановіть його активним
завантажте свої збірки
запустити свій код

коли потрібно перезавантажити код,

вивантажити домен
завантажте свої збірки ще раз
запустити свій код.

Однак це стає складним завданням, оскільки вам потрібно якось підтримувати "стан"
свою програму. Ми використовуємо спеціальну серіалізацію
запам’ятати стан усіх об’єктів, зруйнувати все, завантажити нове
збірки, відтворити всі об'єкти та переналаштувати їх такими, якими вони були.
нелегке завдання будь-яким способом.

також переконайтеся, що ви завантажуєте свої збірки з пам'яті, а не з
диск. принаймні на вікнах, якщо ви прочитаєте їх з диска, вас не буде
дозволено
перезапишіть свої збірки новими.

розвантаження/перезавантаження домену - це трохи горезвісна область, з великою кількістю
витоки пам'яті та помилки. здебільшого тому, що це спосіб використання моно, а не того
багато людей, здається, роблять. Я б сказав, з усіх моно пов'язаних
Я працюю в Unity, близько 80% пов'язано з проблемами, що стосуються домену
розвантаження.