[C#]Uvolnenie dynamicky nacitaj DLL

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod TomasXXG 23. 6. 2013 12:16

Dobry den. Neviem prist na to ako uvolnit dynamicky nacitanu DLL kniznicu. Chcem to urobit preto, lebo si ju dynamicky vytvaram. Problem je, ze ked ju nacitam tak nemozem potom zase vytvorit druhu verziu DLL, pretoze nemam pristup k danemu suboru trieda.dll. Ide to az ked restartujem program. Na internete som nasiel, ze sa uvolnenenie nacitanej DLL robi cez Appdomain.

tu je moj kod:
Kód: Vybrat vše
AppDomain domain = AppDomain.CreateDomain("domain");

            Assembly asm = domain.Load(@"trieda");

            var ins = domain.CreateInstance("trieda", "ClassLibrary1.Class1");

            Type trieda = asm.GetType("ClassLibrary1.Class1");
            try
            {
                MethodInfo metoda = trieda.GetMethod("moja_metoda");
                if (metoda != null)
                {
                    try
                    {
                        Dictionary<string, double> vst_data = new Dictionary<string, double>();
                        foreach (DataGridViewColumn col in dataGridView1.Columns)
                        {
                            double hodnota = Double.Parse(dataGridView1[col.Name, 0].Value.ToString());
                            vst_data.Add(col.Name, hodnota);
                        }
                        double vyst_hodnota = (double)metoda.Invoke(ins, new object[] { vst_data });
                        MessageBox.Show(vyst_hodnota.ToString());
                    }
                    catch
                    {
                        MessageBox.Show("Neplatne vstupne parametre!");
                    }
                }
                else MessageBox.Show("Metodu sa nepodarilo najst!");
            }
            catch
            {
                MessageBox.Show("Triedu sa nepodarilo najst!");
            }
            AppDomain.Unload(domain);​

problem je, ze stale nieje DLL uvolnena, stale nemam pristu ku danemu suboru triedy, aby som mohol zakompilovat novy kod. Kde je chyba?
Naposledy upravil Vebloud dne 24. 6. 2013 20:34, celkově upraveno 1
Důvod: Název tématu nebyl dle pravidel a chyběl code tag, nauč se to nebo ti budu zamykat vlákna
TomasXXG
Junior

Odeslat příspěvekod root 23. 6. 2013 12:57

Zdravím, mnohem přehledněji by to vypadalo kdyby jste Váš kód vložil do
Kód: Vybrat vše
kód
společně s formátováním.

http://stackoverflow.com/questions/4586 ... appdomains

V C# nejsem expertem, pokud to má být více jako domácí úkol, jsem schopný se na to podívat hlouběji.

S pozdravem,
root
Junior
Uživatelský avatar

Odeslat příspěvekod hunter21 23. 6. 2013 13:32

Ked pouzijes rozdielny nazov .DLL mozes v tom istom case pouzit obidve kniznice v ktorych sa mozu nachadzat aj rovnake procedury.
Bohuzial Win nieje Lin, kde je mozne mat natiahnute rozne kniznice s tym istym nazvom.
hunter21
Pokročilý

Odeslat příspěvekod root 23. 6. 2013 13:47

hunter21 píše:Ked pouzijes rozdielny nazov .DLL mozes v tom istom case pouzit obidve kniznice v ktorych sa mozu nachadzat aj rovnake procedury.
Bohuzial Win nieje Lin, kde je mozne mat natiahnute rozne kniznice s tym istym nazvom.

Bože to je zase blábol...
C# dynamic linked library (.dll) není shared object (.so), ale nějaká zhovadilost stejně jako "tyto" knihovny např. v Javě.

Pokud se budeme bavit na úrovni OS, tak equivalentem .so je Win32 .dll.
Opravdu nechápu snahu těchto Vám podobných pisálků (prudičů) se takto viditelně (a zcela bez potřeby) shazovat né-li přímo ztrapňovat.

Zdravím do hor.
Naposledy upravil root dne 23. 6. 2013 13:50, celkově upraveno 1
root
Junior
Uživatelský avatar

Odeslat příspěvekod herceg.tomas 23. 6. 2013 13:50

hunter21: Kecáte blbosti, tohle nemá s názvem knihovny vůbec nic společného a i na Windows lze načíst do paměti dvě knihovny se stejným názvem.


.NET neumožňuje z paměti uvolnit knihovnu, kterou si tam načtete - knihovny obsahují spustitelný kód a když knihovnu odstraníte z paměti, mohly by na heapu zbýt objekty, které na kódu z té knihovny závisejí, tudíž tohle nejde - je to omezení by design.
Jediná možnost, jak to udělat, je načíst tu knihovnu do té appdomény a pak zrušit celou appdoménu, což také děláte.
Potíž je v tom, že pokud chcete pracovat s instancí v jiné appdoméně, musíte použít CreateInstanceAndUnwrap a ta třída musí dědit z MarshallByRefObject, případně být označena atributem Serializable. Tím se instance vytvoří v dané appdoméně a vy dostanete pouze jakýsi proxy objekt, který bude všechna volání přesměrovávat do dané app domény.

Funkční příklad je např. http://social.msdn.microsoft.com/Forums ... -appdomain
Místo MarshallByRefType dejte typ té Vaší třídy, jen se ujistěte, že to dědí z MarshallByRefObject.
herceg.tomas
Kolemjdoucí

Odeslat příspěvekod root 23. 6. 2013 13:52

Smekám! První normální "rada" zde na fóru!
Opravdu.
root
Junior
Uživatelský avatar

Odeslat příspěvekod piErcE 23. 6. 2013 14:54

Root: nic ve zlem, ale to co jsi napsal v tom svém úvodním pojednání, co je to dll, jsi vyplodil Presne stejný zvast, jaké jsi v tom prispevku zkritizoval.

budes se divit, ale DLL vylezla z .netu je úplně obyčejná win32 dll, cili ano...i u takové DLL plati analogie s .so, kterou ty přisuzuješ prave win32 dllkum.
piErcE
Junior

Odeslat příspěvekod TomasXXG 23. 6. 2013 15:06

Problem je v tom, ze nemam pristupove prava k soboru DLL ked ho nacitam.
Kód: Vybrat vše
byte[] subor = System.IO.File.ReadAllBytes("trieda.dll");
domain = AppDomain.CreateDomain("domain");
asm = domain.Load(subor);

Aj ked subor DLL nacitam najskor do pola bytov tak mi tiez pri pokuse znova skompilovat DLL vypise chybu, ze pristup k suboru bol odmietnuty.
Neda sa to vyriesit nejak jednoducho?
TomasXXG
Junior

Odeslat příspěvekod root 23. 6. 2013 15:08

piErcE píše:Root: nic ve zlem, ale to co jsi napsal v tom svém úvodním pojednání, co je to dll, jsi vyplodil Presne stejný zvast, jaké jsi v tom prispevku zkritizoval.

budes se divit, ale DLL vylezla z .netu je úplně obyčejná win32 dll, cili ano...i u takové DLL plati analogie s .so, kterou ty přisuzuješ prave win32 dllkum.


Nerad bych to rozebíral detailněji, ale můj úvodní post byl stručnou reakcí, nikoliv pokus o sálodlouhé vysvětlování v čem se dotyčný mýlí, toť vše.

http://forums.asp.net/t/1536669.aspx/1

PS: Nějak jsem si nevšiml, že my dva bysme spolu někdy pásli husy a tudíš bych očekával jednání mimo tuto ryze Českou specialitku.

TomasXXG píše:Problem je v tom, ze nemam pristupove prava k soboru DLL ked ho nacitam.
Kód: Vybrat vše
byte[] subor = System.IO.File.ReadAllBytes("trieda.dll");
domain = AppDomain.CreateDomain("domain");
asm = domain.Load(subor);

Aj ked subor DLL nacitam najskor do pola bytov tak mi tiez pri pokuse znova skompilovat DLL vypise chybu, ze pristup k suboru bol odmietnuty.
Neda sa to vyriesit nejak jednoducho?

Tomuto nějak nerozumím...
Není problém v tom, že je na tom .dll souboru nějaký zámek, například kvůli jeho nezavření?
root
Junior
Uživatelský avatar

Odeslat příspěvekod TomasXXG 23. 6. 2013 17:28

Pokial sa nevykona prikaz
Kód: Vybrat vše
asm = domain.Load(subor);
tak mozem subor prepisat aj nacitat do pola bytov x-krat bez problemov. K suboru je zakazany pristup az ked sa vykona uvedeny prikaz.
TomasXXG
Junior

Odeslat příspěvekod root 23. 6. 2013 17:52

Kód: Vybrat vše
AppDomain.Unload(asm);
root
Junior
Uživatelský avatar

Odeslat příspěvekod TomasXXG 23. 6. 2013 22:01

Kód: Vybrat vše
AppDomain.Unload(asm);
tento kod nefunguje, pretoze mozem uvolnit len AppDomain a asm je typu Assembly. AppDomain bezne uvolnujem aj tak mi to nepomaha...

-- 23. 6. 2013 23:15 --

Nakoniec som to vyriesil tak, ze som nepouzil Appdomin ale len samotne Assembly, subor som nacital ako pole bytov a vsetko ide ako ma...
TomasXXG
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků