Dezvoltăm un joc și folosim C # și C ++ cu ajutorul mono.

reîncărcarea

Există două DLL pe care le folosim; Dll1 și Dll2. În timpul rulării, vreau să schimb (actualizez) aceste DLL fără a reporni jocul (care durează puțin). Iată codul pe care îl folosim:

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);

Am încercat două moduri diferite, dar niciuna nu a avut succes. Nici nu știu care este eroarea exactă, deoarece nu știu cum să depanez mono în C++.

Prima abordare a fost de a utiliza mono_jit_cleanup și apoi, când DLL-urile sunt recompilate, folosiți codul de mai sus pentru a reîncărca DLL-urile.

A doua abordare a fost închiderea ansamblurilor și imaginilor și redeschiderea lor atunci când DLL-urile sunt înlocuite.

Am făcut o greșeală și/sau există o modalitate de a face acest lucru?

Odată ce un ansamblu a fost JITed (ceea ce înseamnă în principiu asta
una dintre metodele sale a fost invocată), nu există nici o modalitate de a o schimba.

Există 2 moduri de a reîncărca un ansamblu:

1) schimbați numele ansamblului și încărcați-l din nou. Rețineți că acest lucru
nu va descărca/elibera tipurile furnizate de ansamblul anterior,
nici tipurile ansamblului reîncărcat nu sunt compatibile cu cele ale
primul. Cu alte cuvinte: nu o faceți decât dacă ați făcut-o
a înțeles aceste dezavantaje.

2) Folosiți domenii de aplicații care pot fi descărcate împreună cu
ansamblurile lor prin proiectare.

Acesta este un model comun în cuvântul .NET și poate fi

implementat cu ușurință în cod gestionat. Sunt destule
documente/eșantion pe internet.

Mulțumesc pentru răspunsul rapid.

Ok, știu cum să fac asta în C #. Există o modalitate de a crea
domeniu de aplicație folosind mono în C ++? Dacă există, pot crea
monoDominiul meu și ansamblurile din acel domeniu de aplicații, astfel încât să le pot descărca.

În caz contrar, nu mă va ajuta să creez un domeniu de aplicații în C # de la
DLL-urile pe care vreau să le schimb sunt blocate de mono în C++.

Ei bine, nu contează cu adevărat cine creează domeniile
și încărcarea ansamblurilor. Este de departe mai ușor de implementat
aceasta în C # și apoi mono_runtime_invoke din C++.

Desigur, puteți invoca totul de la C ++, dar acest lucru va fi
probabil să triplice cantitatea de cod care trebuie scrisă.

În plus, singura modalitate sigură de a crea un domeniu în C ++ este
mono_runtime_invoke-ing System.AppDomain.CreateDomain (), IIRC.

puteți utiliza mono_domain_create () și mono_domain_unload () foarte bine de la
c. De fapt, bănuiesc că este de fapt
mai ușor de făcut din codul nativ în aceste zile. practic ceea ce ar trebui să faceți este:

creați un domeniu
setați-l activ
încărcați-vă ansamblurile
rulați codul

când doriți să reîncărcați codul,

descărcați domeniul
încărcați-vă din nou ansamblurile
rulați codul.

Totuși, devine dificil, deoarece trebuie să păstrați cumva „starea” de
programul dvs. Folosim serializarea personalizată
să ne amintim de starea tuturor obiectelor, să dărâmăm totul, să încărcăm noi
ansambluri, recreează toate obiectele și reconfigurează-le așa cum erau.
nu este o sarcină ușoară.

de asemenea, asigurați-vă că încărcați ansamblurile din memorie în loc de din
disc. cel puțin pe Windows, dacă le citiți de pe disc, nu veți fi
permis
suprascrieți adunările cu altele noi.

descărcarea/reîncărcarea domeniului este o zonă puțin cunoscută, cu o mulțime de
scurgeri de memorie și erori. mai ales pentru că este o modalitate de a utiliza mono, nu atât
mulți oameni par să facă. Aș spune din toate mono legate
munca pe care o fac la Unity, aproximativ 80% este legată de probleme legate de domeniu
descărcare.