Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Peklo s Dll knihovnama

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

22:36:09 21.12.2009

> Vůbec nic. Řekl bych spíše, že MS nemá nic moc v nabídce. Windows
> Vista, která děkuji nechci a čerstvoučké Windows 7, kde je třeba
> počkat až MS opraví chyby a jak se ukáží.

Nabidka je stejna od dob Windows 2000 - nekolik edic pro servery,
a nekolik edic pro pracovni stanice :-)

V praci pouzivam Windows 7 a doma pouzivam Windows XP. Osobne povazuju
Windows 7 za jakysi major service pack pro Windows Vista. Rekl bych ze
Windows 7 jsou onim operacnim systemu, kde MS opravil chyby.
Bezi podstatne lepe a rychleji, nez Windows Vista, ale na Windows XP
budu zrejme jeste dlouho a s nostalgii vzpominat.

Windows 7 ma furt UAC (jednou shit, navzdy shit), a tu debilni
souborovou a registrovou virtualizaci kvuli starym a blbe napsanym
programum. Ale pokud se oboje vypne, tak to je celkem OK.

Jedina "cool" funkce ktera mne ve Windows 7 velmi vadi je
chybejici quick launch. Je to ale subjektivni, spousta lidi si
novy taskbar pochvaluje. Ja konzervativni veteran mu ale nemuzu
prijit na chut.

> lidi přijmou jakkoli špatného vůdce jako osvoboditele už jen proto,
> že se zbavili tyrana. Mám pocit, že souslednost WIndows Vista a
> WIndows 7 nápadně tuto Machiavelliho strategii připomíná.

Jo, s tim souhlasim :-)

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: AnonymousUser

18:47:49 21.12.2009

[ital]Jen ciste ze zvedavosti (jo, vim ze je to off topic), co vam na x64 vadi ?[/ital]

Vůbec nic. Řekl bych spíše, že MS nemá nic moc v nabídce. Windows Vista, která děkuji nechci a čerstvoučké Windows 7, kde je třeba počkat až MS opraví chyby a jak se ukáží.

Navíc Windows 7 je bráno jako dobré, protože lidé přijmou už za dobré cokoli, co není Windows Vista. Zde se projevila Machiavelliho strategie: Chcete-li se někde prosadit, pusťte tam nejhoršího vůdce, který bude lidi tyranizovat, po čase ho stáhněte, ideálně popravte a lidi přijmou jakkoli špatného vůdce jako osvoboditele už jen proto, že se zbavili tyrana. Mám pocit, že souslednost WIndows Vista a WIndows 7 nápadně tuto Machiavelliho strategii připomíná.

Chci chvíli počkat a pak si vyzkoušet, jestli Windows 7 jsou dobrá, protože jsou dobrá, a nebo jsou dobrá jen proto, že to nejsou Visty. Ve druhém případě stále pojedu na XP a přestoupím asi na BSD. V prvním případě si je pořídím.

Nikdy v minulosti neměl MS tak mizernou a velmi skrovnou nabídku jako dnes.

Miloslav Ponkrác
[url]http://ponkrac.net/complex-web-server[/url]
[url]http://ponkrac.net/complex-web-server[/url]

Citovat příspěvek

 

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

9:26:17 21.12.2009

Diky as info, tohle jsem nevedel.

> nutnost. (Pro začátek by mohl MS konečně udělat pořádnou verzi Windows pro x86/x64 platformu.)

Jen ciste ze zvedavosti (jo, vim ze je to off topic), co vam na x64 vadi ?

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: AnonymousUser

18:47:51 19.12.2009

[ital]Taky se mi kdysi stal podobny pripad, kdyz jsem po tom patral, tak
jsem zjistil ze CRT cast, kterou do kazdeho DLL pridava Microsoft,
si vyrabi vlastni heap. Tedy kazda DLL ma vlastni heap, ze ktereho
"cerpaji" operace jako calloc, malloc, a new.[/ital]

Ano, proto píšu, že ani C DLL nemusí být přenositelné.

[ital]Duvod, proc se pouziva takove zarovnani, ktere jsem popsal, je v
procesoru - kvuli rychlosti procesor pozaduje, aby jakakoliv promenna
v pameti byla zacinala na adrese delitelne jeji velikosti.[/ital]

To také nemusí být pravda. Rychlostně potřebuje procesor hlavně netahat/zapisovat z paměti přes hranici cache a natáhnout to z cachí a ram na co nejmenší počet cyklů. Zarovnání to není schopno zajistit.

Proto nastupuje další podmínka, a to zarovnanost všeho možného (začátků struktur, stacků atd.) na 16 bajtů, která je nutnou podmínkou pro max. rychlost procesoru + samozřejmě Intel už se na to vybodl, aby řešil data na libovolných adresách všude a některé SIMD instrukce už natvrdo požaduje takto zarovnané.

Nicméně zarovnanost struktur má také zpomalující efekt – taková struktura zabírá více místa v paměti a způsobuje nižší účinnost cachí, čímž klesá rychlost velmi rapidně a tvrdě.

Upřímně, pokud by byla podmínkou max. rychlost, pak by se musely struktury zarovnávat jinak. A to tak, aby data byla co nejvíce u sebe, a nikdy nepřesahovala hranici 16 bajtového násobku adresy (pokud samozřejmě člen struktury se do 16 bajtů vejde). Na ostatní pravidla by se kašlalo, klidně ať si int začíná třetím bajtem struktury, je to fuk. Samotná struktura by začínala na adrese dělitelné 32. Takto zarovnaná struktura by způsobila nejvyšší rychlost zpracování dat a využila možnosti rychlosti procesoru na maximum. To se ovšem neděje, takže argumentovat zarovnáním jako rychlostí je na půl cestě.

Ve skutečnosti se zarovnává proto, že Windows byly kdysi portovány na jiné procesory, které zarovnání tvrdě vyžadovaly. Postupem času se sice MS na tyto platformy vybodl, ale stále je připraven převálcovat cokoli a připravit Windows na platformu, ze které by káplo na tržbách aspoň pár desítek miliard dolarů a Windows API s tímto počítá. Win API je teoreticky platformě a procesorově nezávislé API a musí počítat i s procesory, kde zarovnanost je nutnost. (Pro začátek by mohl MS konečně udělat pořádnou verzi Windows pro x86/x64 platformu.)

Takže z mého pohledu je počínání pana Valeriana vysoce logické na x86 platformě.

[ital]Ano. Predavani ven vrele nedoporucuju. Drz se jednoducheho char *,
pripadne wchar_t *.[/ital]

Takže jsme se oklikou dostali přes zamítnutí mého tvrzení, že přenositelné a bezpečné v DLL jsou jen ukazatele a inty zpět k tomu, že jste potvrdili platnost toho co jsem napsal. Děkuji. :-)

Miloslav Ponkrác
[url]http://ponkrac.net/complex-web-server[/url]
[url]http://ponkrac.net/pisma/[/url]

Citovat příspěvek

 

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

17:37:37 05.12.2009

Vybodni se na kompatibilitu, stejne to budes kompilovat
jen ve VC++ :-)

Jinak to, co jsi popisoval, velice pripomina COM model.

Pokud z nejakeho duvodu potrebujes prenositelnost mezi prekladaci,
tak to proste udelej tak, aby kazdy plugin exportoval urcitou skupinu
funkci. Neni nutne aby byly seskupene do tridy.

Prikladem jsou treba archivacni pluginy pro Total Commander,
ty take nepouzivaji tridy, ale pouze predem definovanou skupinu funkci
s danou volaci konvenci a s danymi parametry.

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

13:35:55 05.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> No ještě bych se vrátil k návrhu mých tříd. Jak
> jsem psal, návrh vychází přibližně z takovéhle
> představy:
> http://www.abstraction.net/ViewArticle.aspx?articl
> eID=67 . Pan Valerian mi tento navrh rozmlouval a
> pravděpodobně ví o čem mluví (protože opravdu
> kompatibilita takto vytvořených dll knihoven není
> napříč kompilátory moc dobrá).
>
> Mě ale tento návrh prostě fascinuje - připadá mi
> to jako zajímavé řešení, které zdá se je i dost
> používané, nechci se prostě těch tříd vzdát :-)...
>[/color]

V tom případě to musíte dělat jen v rámci téhož překladače.

[color=#008000]>
> Když jsem hledal jiné řešení, všiml jsem si tohoto
> (http://www.nuclex.org/articles/cxx/4-building-a-b
> etter-plugin-architecture) - myslíte, že je to lepší?
> Nechce se mi předělávat celý návrh, abych
> zjistil, že to bude dávat stejný výsledek jako
> současné řešení...
>[/color]

Pro používání tříd napříč různými překladači to není vhodné. Obecně máte jen dvě možnosti.

1. Buď použijte stejný překladač.

2. Nebo použijte již zmíněné API funkce bez používání tříd v kódu vytvořeném různými překladači. Třídy vytvořené v DLL by se měly používat jen v téže DLL. Můžete je předávat i mimo např. jako [b]void *[/b] tj. když např. z exáče zavoláte nějakou API z příslušné DLL a ona vrátí ukazatel [b]void *[/b] což bude ve skutečnosti objekt nějaké třídy vzniklý uvnitř té DLL knihovny, tak jiné API funkci z téže DLL knihovny pak můžete ten ukazatel [b]void *[/b] zase předat v parametru a ta API funkce v té DLL knihovně si ho interně přetypuje zase zpátky na objekt té třídy s níž počítá a pak samozřejmě v rámci DLL může pracovat s instancí té třídy vzniklé uvnitř téže DLL.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

20:04:50 04.12.2009

No ještě bych se vrátil k návrhu mých tříd. Jak jsem psal, návrh vychází přibližně z takovéhle představy: http://www.abstraction.net/ViewArticle.aspx?articleID=67 . Pan Valerian mi tento navrh rozmlouval a pravděpodobně ví o čem mluví (protože opravdu kompatibilita takto vytvořených dll knihoven není napříč kompilátory moc dobrá).

Mě ale tento návrh prostě fascinuje - připadá mi to jako zajímavé řešení, které zdá se je i dost používané, nechci se prostě těch tříd vzdát :-)... Když jsem hledal jiné řešení, všiml jsem si tohoto (http://www.nuclex.org/articles/cxx/4-building-a-better-plugin-architecture) - myslíte, že je to lepší? Nechce se mi předělávat celý návrh, abych zjistil, že to bude dávat stejný výsledek jako současné řešení...

Děkuji.

Citovat příspěvek

 

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

8:11:18 03.12.2009

>> Ano, ale to co se alokuje např. přes malloc nebo
>> new ať už v EXE nebo v DLL,
>> to pak není vhodné uvolňovat mimo tj. jen uvnitř
>> EXE nebo DLL kde to vzniklo.

> Zrovna jsem se rozčiloval, proč ta aplikace padá :-) a stačilo se
> podívat sem :-). To jsem netušil, že zrovna toto nastavení na to
> bude mít vliv. Každopádně jste mi ušetřil jste mi touto radou
> spoustu času a nervů, děkuju. PS: odkud čerpáte takovéto informace?
> Z MSDN, nebo existuje nějaký dobrý seriál článků?

Vlastni bolestne ziskane zkusenosti :-)

Taky se mi kdysi stal podobny pripad, kdyz jsem po tom patral, tak
jsem zjistil ze CRT cast, kterou do kazdeho DLL pridava Microsoft,
si vyrabi vlastni heap. Tedy kazda DLL ma vlastni heap, ze ktereho
"cerpaji" operace jako calloc, malloc, a new.

Behem kazde alokace je nutne zadat handle na heap (viz popis funkci
HeapAlloc a HeapFree). Pokud zadas spatny handle, tak funkce HeapFree
vyhodi vyjimku. To je zrejme duvod proc ti padal tvuj program.

Pokud ale funkce v DLL alokuje pamet pomoci LocalAlloc,
HeapAlloc(GetProcessHeap(), ...) nebo VirtualAlloc, pak je mozne pamet
uvolnit i mimo DLL, kde byla alokovana. Delaji to tak nektere API
funkce, napr. CommandLineToArgvW.

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

19:10:24 02.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> Zrovna jsem se rozčiloval, proč ta aplikace padá
> :-) a stačilo se podívat sem :-). To jsem netušil,
> že zrovna toto nastavení na to bude mít vliv.
> Každopádně jste mi ušetřil jste mi touto radou
> spoustu času a nervů, děkuju. PS: odkud čerpáte
> takovéto informace? Z MSDN, nebo existuje nějaký
> dobrý seriál článků?[/color]

To jsou informace nasbírané za více než 15 let praxe při psaní programů. Spousta informací je z [b]MSDN[/b]. Zrovna problém ohledně uvolňování paměti uvnitř DLL, která byla alokována přes CRT mimo tu DLL je popsán viz odkaz.

[b]Potential Errors Passing CRT Objects Across DLL Boundaries[/b]
http://msdn.microsoft.com/en-us/library/ms235460.aspx

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

17:59:08 02.12.2009

> > Můžu aplikaci kompilovat s příznakem /MD a
> pluginy
> > které se do ní dynamicky načítají s /MT -
> bude to
> > kompatibilní když to pak spolu bude
> > spolupracovat?
> >
>
> Ano, ale to co se alokuje např. přes malloc nebo
> new ať už v EXE nebo v DLL,
> to pak není vhodné uvolňovat mimo tj. jen uvnitř
> EXE nebo DLL kde to vzniklo.

Zrovna jsem se rozčiloval, proč ta aplikace padá :-) a stačilo se podívat sem :-). To jsem netušil, že zrovna toto nastavení na to bude mít vliv. Každopádně jste mi ušetřil jste mi touto radou spoustu času a nervů, děkuju. PS: odkud čerpáte takovéto informace? Z MSDN, nebo existuje nějaký dobrý seriál článků?

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

14:47:39 02.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> Tak aby řeč nestála :-)
>
> Můžu uvnitř v dll používat std::string a
> std::vector? Vlastně proč asi ne, že :-), jen je
> není tak snadné předávat ven...
>[/color]

Tyto záležitosti předávat ven vůbec nedoporučuji tj. používat jen uvnitř příslušné DLL
nebo uvnitř exáče kde to vzniklo bez předávání napříč DLL.

Pokud je potřeba předávat řetězec, který je uložen v typu [b]STL string[/b]
nebo pole v [b]STL vector[/b] pak to lze předávat přes ukazatele viz příklady.

[b]Příklad předání řetězce ze stringu[/b]

V exáči je třeba proměnná typu [b]string[/b] ze [b]STL[/b] a volá se nějaká API funkce
ve Vaší DLL, která přebírá parametr typu [b]char *[/b].

[b]V exáči:[/b]
[size=14px][code][color=#0000FF]string[/color] Exac_str1[color=#800000];[/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]
Exac_str1 [color=#800000]=[/color] [color=#800080]"ABC"[/color][color=#800000];[/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]
NejakaAPiFunkceVeVasiDll[color=#800000]([/color]Exac_str1[color=#800000].[/color]c_str[color=#800000]([/color][color=#800000])[/color][color=#800000])[/color][color=#800000];[/color][/code][/size]
[b]V DLL v té API funkci:[/b]
[size=14px][code][color=#0000FF]extern[/color] [color=#800080]"C"[/color] [color=#0000FF]__declspec[/color][color=#800000]([/color][color=#0000FF]dllexport[/color][color=#800000])[/color] [color=#0000FF]void[/color] NejakaAPiFunkceVeVasiDll [color=#800000]([/color][color=#0000FF]char[/color] [color=#800000]*[/color]Str[color=#800000])[/color]
[color=#800000]{[/color]
[color=#0000FF]if[/color] [color=#800000]([/color]Str[color=#800000])[/color] [color=#800000]{[/color]

[color=#008000]// Pokud to potřebujete pro ulehčení práce s řetězcem ve funkci apod.[/color]
[color=#008000]// pak si v DLL můžete takto předaný parametr char * přiřadit do stringu[/color]
[color=#0000FF]string[/color] DLL_str1 [color=#800000]=[/color] Str[color=#800000];[/color]

[color=#008000]// a dál se ve funkci už může pracovat s DLL_str1 [/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]

[color=#800000]}[/color][color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color][/code][/size]

[b]Příklad předání pole z vectoru[/b]

V exáči je třeba proměnná typu [b]vector [/b] ze [b]STL[/b] a volá se nějaká API funkce
ve Vaší DLL, která přebírá dva parametry parametry [b]int *[/b] a [b]int[/b].

[b]V exáči:[/b]
[size=14px][code]vector [color=#800000]<[/color][color=#0000FF]int[/color][color=#800000]>[/color] Exac_Pole[color=#800000];[/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]
Exac_Pole[color=#800000].[/color]push_back[color=#800000]([/color][color=#0000FF]5[/color][color=#800000])[/color][color=#800000];[/color]
Exac_Pole[color=#800000].[/color]push_back[color=#800000]([/color][color=#0000FF]10[/color][color=#800000])[/color][color=#800000];[/color]
Exac_Pole[color=#800000].[/color]push_back[color=#800000]([/color][color=#0000FF]20[/color][color=#800000])[/color][color=#800000];[/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]
[color=#0000FF]if[/color] [color=#800000]([/color]!Exac_Pole[color=#800000].[/color]empty[color=#800000]([/color][color=#800000])[/color][color=#800000])[/color] [color=#800000]{[/color]
NejakaAPiFunkceVeVasiDll[color=#800000]([/color][color=#800000]&[/color]Exac_Pole[color=#800000][[/color][color=#0000FF]0[/color][color=#800000]][/color][color=#800000],[/color]Exac_Pole[color=#800000].[/color]size[color=#800000]([/color][color=#800000])[/color][color=#800000])[/color][color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color][/code][/size]
[b]V DLL v té API funkci:[/b]
[size=14px][code][color=#0000FF]extern[/color] [color=#800080]"C"[/color] [color=#0000FF]__declspec[/color][color=#800000]([/color][color=#0000FF]dllexport[/color][color=#800000])[/color] [color=#0000FF]void[/color] NejakaAPiFunkceVeVasiDll [color=#800000]([/color][color=#0000FF]int[/color] [color=#800000]*[/color]ptrPole[color=#800000],[/color] [color=#0000FF]int[/color] Delka[color=#800000])[/color]
[color=#800000]{[/color]
[color=#0000FF]if[/color] [color=#800000]([/color]ptrPole [color=#800000]&[/color][color=#800000]&[/color] Delka [color=#800000]>[/color] [color=#0000FF]0[/color][color=#800000])[/color] [color=#800000]{[/color]

[color=#008000]// Pokud to potřebujete pro ulehčení práce s polem ve funkci apod.[/color]
[color=#008000]// pak si v DLL můžete takto předané parametry přiřadit do vectoru[/color]
vector [color=#800000]<[/color][color=#0000FF]int[/color][color=#800000]>[/color] DLL_Pole [color=#800000]([/color]ptrPole[color=#800000],[/color] ptrPole [color=#800000]+[/color] Delka[color=#800000])[/color][color=#800000];[/color]

[color=#008000]// a dál se ve funkci už může pracovat s DLL_Pole typu vector[/color]
[color=#800000].[/color][color=#800000].[/color][color=#800000].[/color]

[color=#800000]}[/color][color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color][/code][/size]

[color=#008000]>
> Můžu aplikaci kompilovat s příznakem /MD a pluginy
> které se do ní dynamicky načítají s /MT - bude to
> kompatibilní když to pak spolu bude
> spolupracovat?
>[/color]

Ano, ale to co se alokuje např. přes [b]malloc[/b] nebo [b]new[/b] ať už v EXE nebo v DLL,
to pak není vhodné uvolňovat mimo tj. jen uvnitř EXE nebo DLL kde to vzniklo.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

14:06:33 02.12.2009

Děkuju za odpověď.

Citovat příspěvek

 

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

14:03:51 02.12.2009

> Můžu uvnitř v dll používat std::string a std::vector? Vlastně proč
> asi ne, že :-), jen je není tak snadné předávat ven...

Ano. Predavani ven vrele nedoporucuju. Drz se jednoducheho char *,
pripadne wchar_t *.

> Můžu aplikaci kompilovat s příznakem /MD a pluginy které se do ní
> dynamicky načítají s /MT - bude to kompatibilní když to pak spolu bude spolupracovat?

Ano. Vyhni se uvolnovani pameti mimo modul, kde byla alokovana.

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

13:59:35 02.12.2009

Tak aby řeč nestála :-)

Můžu uvnitř v dll používat std::string a std::vector? Vlastně proč asi ne, že :-), jen je není tak snadné předávat ven...

Můžu aplikaci kompilovat s příznakem /MD a pluginy které se do ní dynamicky načítají s /MT - bude to kompatibilní když to pak spolu bude spolupracovat?

Předem děkuji za odpovědi.

Citovat příspěvek

 

Re[4]: Peklo s Dll knihovnama

Autor: LadislavZezula

9:54:44 02.12.2009

> Tak to rozhodně nejsou, protože zarovnávání u vlastních API DLL
> si může jejich tvůrce zvolit a já používám vždy 1 a nikdy jsem
> s tím neměl problém.

Duvod, proc se pouziva takove zarovnani, ktere jsem popsal, je v
procesoru - kvuli rychlosti procesor pozaduje, aby jakakoliv promenna
v pameti byla zacinala na adrese delitelne jeji velikosti.
Pokud se tak nestane a procesor narazi treba na instrukci,
kde ma nacist DWORD z liche adresy, pak se podiva do registru
EFLAGS a CR0. Pokud jsou v obou nastavene prislusne bity,
tak procesor vyhodi vyjimku.

Nastesti, ve Windows je alignment check zakazany, takze nezarovnane
promenne procesor bez reptani spolkne. Pokud zkusite oba bity nastavit
nasilne, treba pomoci kernel debuggeru, system pujde do modre,
protoze ani Windows nejsou v tomto ohledu svate.

Mno a protoze co je ve Windows jednou dano, to se s nejvetsi
pravdepodobnosti MS nikdy nepokusi zmenit (jednou sracka - navzdy
sracka :-)), tak s tim asi ani zadne problemy mit nebudete.

L.



Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Re[2]: Peklo s Dll knihovnama

Autor: JiriValerian

9:12:47 02.12.2009

[color=#008000]LadislavZezula Napsal:
-------------------------------------------------------
> Zajimave. Skoro bych rekl ze vsechny vase DLL jsou
> prelozeny spatne.
>[/color]

Tak to rozhodně nejsou, protože zarovnávání u vlastních API DLL
si může jejich tvůrce zvolit a já používám vždy 1 a nikdy jsem
s tím neměl problém.

Citovat příspěvek

 

Re[2]: Peklo s Dll knihovnama

Autor: LadislavZezula

9:04:04 02.12.2009

> Win API je přeloženo se zarovnáváním struktur 1, a to používám
> i já u všech svých API DLL.

Zajimave. Skoro bych rekl ze vsechny vase DLL jsou prelozeny spatne.

Struktury pro Win32 jsou zarovnany na 8, ne na 1.
Nicmene, neznamena to ze kazda promenna struktury zacina
na offsetu delitelnem 8mi. Prekladac je umisti vzdy na
offset delitelny velikosti. TO znamena, ze promenna velikosti 1 byte
muze byt unistena kdekoliv, ale promenna velikosti 4 byty pouze na
offsetu delitelnem 4mi.

Myslim ze nejlepsi pripad z praxe je struktura UNICODE_STRING:

typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

Na 32 bitovem systemu vypada takto:

Offset 00 (2 byty) Length
Offset 02 (2 byty) MaximumLength
Offset 04 (4 byty) Buffer

Na 64bitovem systemu vyoada takto:

Offset 00 (2 byty) Length
Offset 02 (2 byty) MaximumLength
Offset 04 (4 byty) **NOTHING**
Offset 08 (8 bytu) Buffer

Je zrejme, ze prekladac umistil
8-bytovy pointer na adresu delitelnou 8mi, tedy na offset 8.
Z toho vyplyva ze zarovnani Win API nemuze byt 1.

Nicmene:

Drtiva vetsina struktur pouzivanych ve Win API
je navrzena tak, ze 4-bytove promenne jsou na offsetu dwelitelnem 4mi.
Prikladem budiz promenna ACL:

typedef struct _ACL {
UCHAR AclRevision;
UCHAR Sbz1; // pouze pro zarovnani
USHORT AclSize;
USHORT AceCount;
USHORT Sbz2; // Pouze pro zarovnani
} ACL;
typedef ACL *PACL;

Dalsi priklady:

typedef struct _TEST_STRUCT
{
BYTE OneByte;
DWORD OneDword;
} TEST_STRUCT, *PTEST_STRUCT;

sizeof(TEST_STRUCT) vraci 8, ale:

#pragma pack(1)
typedef struct _TEST_STRUCT
{
BYTE OneByte;
DWORD OneDword;
} TEST_STRUCT, *PTEST_STRUCT;
#pragma pack()

sizeof(TEST_STRUCT) vraci 5, coz je ale samozrejme spatne kvuli
zarovnani.





Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

9:02:21 02.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> Děkuju za veškeré rady. Vidím, že je to celkem
> věda a já jsem si s tím tak moc hlavu nelámal -
> normálně předávám z Dll knihovny ukazatel na
> strukturu.
>
> Pořád řeším problém v nastavení kompilátoru, ale
> možná je problém v celém návrhu, mohli byste se na
> to znaleckým okem podívat.[/color]

To co uvádíte je pro daný účel napříč různými překladači nevhodné.
Používejte klasické API funkce a nikoli třídy.
Inspirujte se podle příkladu, který jsem uvedl viz odkaz:
http://forum.builder.cz/read.php?23,3185006,3185301#msg-3185301

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

8:46:27 02.12.2009

Děkuju za veškeré rady. Vidím, že je to celkem věda a já jsem si s tím tak moc hlavu nelámal - normálně předávám z Dll knihovny ukazatel na strukturu.

Pořád řeším problém v nastavení kompilátoru, ale možná je problém v celém návrhu, mohli byste se na to znaleckým okem podívat. Děkuju.

Zde je schematicky ukázána strukrura (převzato z http://willperone.net/Code/codedll.php):

----------------------------------------------
Mám společný hlavičkový soubor Base.h (společný pro aplikaci i pluginy) - to je takové rozhraní...

class Base
{
public:
static char c; // some reference counter or whatever

int a, b;

Base()
{
c++;
}

virtual ~Base()
{
...
}

virtual void func()= 0; // this is an abstract base class
};

char Base::c= 0;

----------------------------------------------
Dále mám v každém pluginy dva soubory Plugin.h a Plugin.cpp

plugin.h:

class Plugin: public Base
{
public:
virtual void func()
{
a= 5;
b= 6;
c++;
}
};

------------------------
plugin.cpp

extern "C" __declspec(dllexport) Base *CreatePlugin()
{
return new Plugin();
}


--------------------------------
V aplikaci to potom načítám takhle:

#include

typedef Base *(*CreatePlugin)(); // create a function pointer type that points to CreatePlugin

HINSTANCE hinst= LoadLibrary("whateverdll.dll");
if (hinst)
{
CreatePlugin ctor= (CreatePlugin)GetProcAddress(hinst, "CreatePlugin");
Base *test= ctor();
test->func(); // call the func defined in Plugin, not in Base or Derived
delete test; // calls Plugin's dtor

FreeLibrary(hinst);
}

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

8:27:37 02.12.2009

[color=#008000]AnonymousUser Napsal:
-------------------------------------------------------
> Které Win API používá přímo strukturu...
> Myslím strukturu, ne ukazatel na strukturu?[/color]

Jen namátkou viz odkazy.

[b]ChildWindowFromPoint Function[/b]
Ve druhém parametru se předává přímo struktura POINT a nejedná se o ukazatel.
http://msdn.microsoft.com/en-us/library/ms632676(VS.85).aspx

[b]MonitorFromPoint Function[/b]
V prvním parametru se předává přímo struktura POINT a nejedná se o ukazatel.
http://msdn.microsoft.com/en-us/library/dd145062(VS.85).aspx

[b]PtInRect Function[/b]
Oba parametry jsou struktura. První parametr RECT * je ukazatel na strukturu,
ale ve druhém se předává přímo struktura POINT a nejedná se o ukazatel.
http://msdn.microsoft.com/en-us/library/dd162882(VS.85).aspx

[color=#008000]>
> I ten ukazatel na strukturu, s tím si můžete pěkně
> naběhnout, protože stačí jiné zarovnání položek
> struktury a je neštěstí hotovo.
>[/color]

Já používám u všech svých API DLL zarovnáváním struktur 1.

Aby se předešlo zmatkům je vhodné napsat do hlavičkového souboru *.h šířeného s příslušnou knihovnou
informaci o tom s jakým zarovnáváním je API DLL přeložena.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: AnonymousUser

3:41:09 02.12.2009

[ital]Bez problémů používám napříč různými překladači C/C++ všechny základní typy počínaje char a konče double i struktury přímo jejich definicí typu v rámci hlavičkového souboru *.h šířeného s příslušnou DLL a zatím jsem s tím nikdy neměl problém. Ostatně i Win API knihovny jsou toho důkazem, protože používají spoustu různých struktur a u některých Win API funkcích používají v rámci parametrů i reálná čísla ať už přímo v rámci parametrů ať předávaných hodnotou nebo i přes ukazatel nebo přes strukturu viz např.[/ital]

Které Win API používá přímo strukturu, nebo vrací strukturu? Myslím strukturu, ne ukazatel na strukturu?

Každý kompilátor předává/vrací strukturu do funkcí trochu jinak.

I ten ukazatel na strukturu, s tím si můžete pěkně naběhnout, protože stačí jiné zarovnání položek struktury a je neštěstí hotovo.

Miloslav Ponkrác

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

22:45:24 01.12.2009

[color=#008000]AnonymousUser Napsal:
-------------------------------------------------------
> Pokud chcete tedy vytvořit přenositelnou DLL
> knihovnu, musíte se velmi omezit, co procpete jako
> API interface funkce. Nedá se procpat žádný
> objekt, žádná výjimka, ba dokonce ani reálné číslo
> nemusí být neproblematické.
>[/color]

Bez problémů používám napříč různými překladači [b]C/C++[/b] všechny základní typy počínaje [b]char[/b] a konče [b]double[/b] i struktury přímo jejich definicí typu v rámci hlavičkového souboru [b]*.h[/b] šířeného s příslušnou [b]DLL[/b] a zatím jsem s tím nikdy neměl problém. Ostatně i Win API knihovny jsou toho důkazem, protože používají spoustu různých struktur a u některých Win API funkcích používají v rámci parametrů i reálná čísla ať už přímo v rámci parametrů ať předávaných hodnotou nebo i přes ukazatel nebo přes strukturu viz např.

[b]SetMiterLimit Function[/b]
http://msdn.microsoft.com/en-us/library/dd145076(VS.85).aspx

[b]CombineTransform Function[/b]
http://msdn.microsoft.com/en-us/library/dd183466(VS.85).aspx

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: AnonymousUser

22:29:48 01.12.2009

Vidím, že bych měl upřesnit:

C++ DLL nejsou přenositelné mezi verzemi.

Pozor! Ani C DLL nemusí být přenositelné, i když velmi často jsou.

Pokud se velmi omezíte a použijete C rozhraní (a ani to ne v plné šíři), pak vytvoříte DLL, která je přenositelná nejen mezi verzemi kompilátoru, ale dokonce i mezi různými programovacími jazyky. Ba dokonce je požadováno, aby projekty kompilátoru používající společnou DLL měly určité stejné volby kompilace.

Nicméně vytvoření přenositelné DLL knihovny musí být záměr, musí to být v projektu, či kódu jasně vyjádřeno, veškeré API funkce (DLL interface) musí mít C názvy (tedy s extern "C") a v zásadě smíte používat jako parametry, či návratové hodnoty funkcí jen integer a ukazatele na cokoli, nic jiného.

Pokud chcete tedy vytvořit přenositelnou DLL knihovnu, musíte se velmi omezit, co procpete jako API interface funkce. Nedá se procpat žádný objekt, žádná výjimka, ba dokonce ani reálné číslo nemusí být neproblematické.

Tedy vytvořit přenositelnou DLL jde, ostatně Win API nic jiného, než sada takových DLL není. Stejně tak se to dělá v programech a pod. Je to ovšem omezující, a proto se to dělá jen když je na to požadavek.

Pokud jen automaticky přeložíte, vyrobíte nepřenositelnou. Chcete-li přenášet objekty (a virtuálními funkcemi) napříč DLL, jde to ztuha, a jen pokud se vzdáte přenášení výjimek a RTTI + zůstanete u komilátoru jednoho výrobce kvůli dekorovaným názvům + pokud možno nebudete lítat o moc verzí (rozptyl několik verzí kompilátoru to snese). A samozřejmě v rámci C++ překladačů jednoho výrobce.

Miloslav Ponkrác
[url]http://ponkrac.net/complex-web-server[/url]
[url]http://ponkrac.net/pisma/[/url]

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

22:20:20 01.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> Bohužel nejsem v tomto tak dobře znalý. Já
> knihovny vytvářím přes win32 a poté vyberu Console
> Application a poté zaškrtnu dll project.
> Nevyužívám žádné MFC, CLR - nic takového...
>[/color]

[b]MFC, CLR[/b] ani nic takového k tomu samozřejmě není vůbec potřeba.

[code]Projekt se ve [b]Visual C++ 2008[/b] vytvoří jako
[b]Project types: Win32[/b]
[b]Visual Studio installed templates[/b]
[b]Win32 Console Application[/b]

a v dalším kroku se pro [b]Application type:[/b] zaškrtne [b]DLL[/b][/code]

[size=20px][color=#000080][b]Pro daný účel podstatná nastavení projektu Win32[/b][/color][/size]

[code][b]Project[/b] ->
[b]Properties[/b] ->
[b]Configuration properties[/b] ->

[b]Configuration:[/b] nastavit na [b]Active(Release)[/b]

[b]C/C++[/b] ->
[b]Code Generation[/b] ->
[b]Runtime Library[/b] nastavit na [b]Multi-threaded (/MT)[/b]

// Pro kompatabilitu s Win API
[b]Struct member Alignment[/b] nastavit na [b]8 Bytes (/Zp8)[/b]

[b]Advanced[/b] ->
[b]Calling Convention[/b] nastavit na [b]__cdecl (/Gd)[/b]
[b]Compile As[/b] nastavit na [b]Compile as C++ Code (/TP)[/b][/code]

[hr]
[size=20px][color=#000080][b]Obsah souboru dllmain.cpp[/b][/color][/size]

[size=14px][code][color=#0000FF]#include[/color] [color=#800080][/color]

HINSTANCE Global_hInst [color=#800000]=[/color] NULL[color=#800000];[/color]

[color=#0000FF]extern[/color] [color=#800080]"C"[/color] [color=#0000FF]__declspec[/color][color=#800000]([/color][color=#0000FF]dllexport[/color][color=#800000])[/color] HINSTANCE GetHInstThisDll [color=#800000]([/color][color=#0000FF]void[/color][color=#800000])[/color]
[color=#800000]{[/color]
[color=#0000FF]return[/color] Global_hInst[color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color]

BOOL APIENTRY DllMain[color=#800000]([/color] HMODULE hModule[color=#800000],[/color]
DWORD ul_reason_for_call[color=#800000],[/color]
LPVOID lpReserved [color=#800000])[/color]
[color=#800000]{[/color]
[color=#0000FF]switch[/color] [color=#800000]([/color]ul_reason_for_call[color=#800000])[/color]
[color=#800000]{[/color]
[color=#0000FF]case[/color] DLL_PROCESS_ATTACH[color=#800000]:[/color]
Global_hInst [color=#800000]=[/color] [color=#800000]([/color]HINSTANCE[color=#800000])[/color]hModule[color=#800000];[/color]
[color=#0000FF]case[/color] DLL_THREAD_ATTACH[color=#800000]:[/color]
[color=#0000FF]case[/color] DLL_THREAD_DETACH[color=#800000]:[/color]
[color=#0000FF]case[/color] DLL_PROCESS_DETACH[color=#800000]:[/color]
[color=#0000FF]break[/color][color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color]
[color=#0000FF]return[/color] TRUE[color=#800000];[/color]
[color=#800000]}[/color][color=#800000];[/color][/code][/size]

[hr]
[size=20px][color=#000080][b]Obsah souboru DllTest.def (zvýrazněno červeně)[/b][/color][/size]

[code][color=#FF0000][b]LIBRARY DllTest.dll
EXPORTS
GetHInstThisDll @1[/b][/color][/code]

Soubor [b]DllTest.def[/b] vytvořit třeba v [b]Notepadu[/b], uložit ho do adresáře projektu
a přidat ho do projektu přes [b]Project[/b] -> [b]Add Existing Item...[/b]

[hr]

Když si pak vzniklou knihovnu DLL prohlédnete utilitou, která je volně ke stažení viz odkaz tak zjistíte,
že obsahuje jednu exportovanou API funkci čistého názvu [b]GetHInstThisDll[/b] bez dekorace.

[b]Dependency Walker[/b]
http://www.dependencywalker.com/

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

21:30:50 01.12.2009

Bohužel nejsem v tomto tak dobře znalý. Já knihovny vytvářím přes win32 a poté vyberu Console Application a poté zaškrtnu dll project. Nevyužívám žádné MFC, CLR - nic takového...

JiriValerian Napsal:
-------------------------------------------------------
> ja___ Napsal:
> --------------------------------------------------
> -----
> > Děkuju za odpověď. Po tak dlouhém trápení se
> s
> > těma dll knihovnama jsem dokonce takovou
> odpověď
> > očekával.
> > Přesto bych měl ještě jeden dotaz - když
> jsou
> > třeba vyvíjeny dll knihovny jako rozšíření
> (třeba
> > miranda-im), to mají vývojáři předepsánu
> > konfiguraci (dané vývojové prostředí,
> nastavení),
> > ve kterém musí pluginy vytvářet, nebo jak se
> to řeší?
> >
>
> Ona ta odpověď co Vám napsal pan Pokrác se netýká
> API DLL, které se dají
> vytvořit tak, že jsou použitelné napříč
> nejrůznějšími překladači. Ostatně
> klasické systémové Win API DLL knihovny jsou toho
> důkazem.
>

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

21:22:38 01.12.2009

[color=#008000]ja___ Napsal:
-------------------------------------------------------
> Děkuju za odpověď. Po tak dlouhém trápení se s
> těma dll knihovnama jsem dokonce takovou odpověď
> očekával.
> Přesto bych měl ještě jeden dotaz - když jsou
> třeba vyvíjeny dll knihovny jako rozšíření (třeba
> miranda-im), to mají vývojáři předepsánu
> konfiguraci (dané vývojové prostředí, nastavení),
> ve kterém musí pluginy vytvářet, nebo jak se to řeší?
>[/color]

Ona ta odpověď co Vám napsal pan Pokrác se netýká API DLL, které se dají
vytvořit tak, že jsou použitelné napříč nejrůznějšími překladači. Ostatně
klasické systémové Win API DLL knihovny jsou toho důkazem.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

21:19:23 01.12.2009

[color=#008000]AnonymousUser Napsal:
-------------------------------------------------------
> Ona je základní blbost vůbec domnívat se, že DLL
> knihovny budou přenositelné mezi různými verzemi
> kompilátoru.
>
> Prosím tohle nikdy nečekejte. C++ tohle nikdy
> nezaručuje a kdo se o to pokusí, je zle
> vytrestán.
>
> Pokud chcete přenášet C++ kód mezi různými
> verzemi, není to možné. Nedělejte to. Nezkoušejte
> to. A pokud to budete zkoušet, nestěžujte si.
>[/color]

Pokud jde o neobjektové DLL tak s tím není problém, protože všechny
linkery včetně Microsoftího umožňují vytvořit DLL s čistými názvy
API funkcí bez dekorací jmen a ty jsou pak samozřejmě použitelné
napříč různými překladači, a to nejen C/C++ podobně jako jsou
použitelné klasické Win API knihovny.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: ja___

21:19:04 01.12.2009

Děkuju za odpověď. Po tak dlouhém trápení se s těma dll knihovnama jsem dokonce takovou odpověď očekával.
Přesto bych měl ještě jeden dotaz - když jsou třeba vyvíjeny dll knihovny jako rozšíření (třeba miranda-im), to mají vývojáři předepsánu konfiguraci (dané vývojové prostředí, nastavení), ve kterém musí pluginy vytvářet, nebo jak se to řeší?

AnonymousUser Napsal:
-------------------------------------------------------
> Ona je základní blbost vůbec domnívat se, že DLL
> knihovny budou přenositelné mezi různými verzemi
> kompilátoru.
>
> Prosím tohle nikdy nečekejte. C++ tohle nikdy
> nezaručuje a kdo se o to pokusí, je zle
> vytrestán.
>
> Pokud chcete přenášet C++ kód mezi různými
> verzemi, není to možné. Nedělejte to. Nezkoušejte
> to. A pokud to budete zkoušet, nestěžujte si.
>
>

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: AnonymousUser

21:01:58 01.12.2009

Ona je základní blbost vůbec domnívat se, že DLL knihovny budou přenositelné mezi různými verzemi kompilátoru.

Prosím tohle nikdy nečekejte. C++ tohle nikdy nezaručuje a kdo se o to pokusí, je zle vytrestán.

Pokud chcete přenášet C++ kód mezi různými verzemi, není to možné. Nedělejte to. Nezkoušejte to. A pokud to budete zkoušet, nestěžujte si.

Citovat příspěvek

 

Re: Peklo s Dll knihovnama

Autor: JiriValerian

19:37:02 01.12.2009

Pro toto platí totéž co jsem uvedl viz odkaz:

http://forum.builder.cz/read.php?23,3185029,3185108#msg-3185108

a to včetně toho, že do budoucna už nemáte dávat takovéyo dotazy do [b]konference C/C++[/b], ale sem, protože se týkají specificky [b]Visual C++[/b], pro který je na tomto serveru tato speciální konference.

[b]Moderátor diskuze[/b]

Citovat příspěvek

 

Strana výpisu

1

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: