Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 14. září 2009, 19:04:59 Předmět: Pluginy |
|
|
Ahojte, snazim se trochu zlepsit v c++, chtel bych ve svoji app pridat podporu pluginu. Cetl sem par tutorialu, zacal psat a narazil na problem s kterym si nevim rady.
mam testovaci projekt ktery vytvori so soubor (jsem na linuxu).
kód: |
extern "C" void Test( void * data)
{
}
|
plugin nacitam takhle
kód: |
void *handle;
typedef double Cosine(double);
Cosine * cosine;
void * fn;
char *error;
handle = dlopen("plugin.so", RTLD_NOW);
if (!handle)
{
char * error = dlerror();
fputs(error, stderr);
exit(1);
}
|
tohle projde bez problemu, kdyz ale funkci Test upravim takhle
kód: |
extern "C" void Test( void * data)
{
((Project*) data)->SetName(L"blabla");
}
|
tak pri nacitani pluginu dostanu error :
kód: |
plugin.so: undefined symbol: _ZN17ProjectDefinition7Project7SetNameERKSbIwSt11char_traitsIwESaIwEE
|
Nemam vubec poneti co s tim... musim tridy ktere chci pouzivat z pluginu oznacit nejakym atributem? nebo nejaky parametr pri kompilaci? |
|
Návrat nahoru |
|
 |
pcmaster

Založen: 28. 07. 2007 Příspěvky: 1827
|
Zaslal: 14. září 2009, 19:45:08 Předmět: |
|
|
No podla toho chyboveho hlasenia typujem, ze trieda Project sa nenachadza v Scope tvojej funkcie Test? Cize netusi, co to Project je. Asi tak. _________________ Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est. |
|
Návrat nahoru |
|
 |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 14. září 2009, 19:55:34 Předmět: |
|
|
No kompilace pluginu projede bez problemu, takze tim to asi nebude. ten zdrojak pluginu je asi takhle :
kód: |
#include "ProjectDefinition/Project.h" // include z materskeho projektu
using namespace ProjectDefinition;
extern "C" void Test(void * data)
{
((Project*) data)->SetName(L"HOVNO");
}
|
|
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 14. září 2009, 20:11:50 Předmět: |
|
|
skus pridat pri kompilacii hlavneho programu -rdynamic. to my nasiel google. prida to do tabulky dynamickych symbolov vsetky symboli. nie len pouzite. _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 14. září 2009, 21:20:58 Předmět: |
|
|
mno, problem je v tom, ze se to tu funkci snazi nabindovat behem kompilace, pritom se ma pouzit late-binding (ta funkce by musela byt obsazena v DLLku, aby to fungovalo. pokud chces, aby byla obsazena 'v pointeru na objekt' (pro rejpaly, zjednodussene receno), tak si musis udelat interface, a tu funkci z nej podedit)
ukazka: IProject.h:
kód: |
struct IProject
{
virtual void SetName(const wchar_t*) = 0;
};
|
Project.h:
kód: |
class Project : public IProject
{
public:
virtual void SetName(const wchar_t*) { /* neco udelej */ };
};
|
.cpp:
kód: |
#include "ProjectDefinition/IProject.h" // include z materskeho projektu
using namespace ProjectDefinition;
extern "C" void Test(void * data)
{
((IProject*) data)->SetName(L"HOVNO");
}
|
(mozna kecam, a stacilo by v tom hlavickovem souboru pred jmeno funkce, kterou chces volat z DLL napsat 'virtual'. nicmene, pokud pochopis co jsem tim co jsem napsal chtel rict, tak pochopis i jak to ve skutecnosti funguje) |
|
Návrat nahoru |
|
 |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 14. září 2009, 21:54:02 Předmět: |
|
|
Tak pridal sem pred metodu SetName sluvko virtual a uz to funguje, ale tohle reseni se mi teda vubec nelibi... nejde to jeste nejak jinak? Nechci umoznit pretezovani metod jen proto ze bych je rad volal z pluginu.
-rdynamic se mi zatim nepodarilo vyzkouset kvuli debilite linuxovych IDE, zatim sem neprisel na to kde to nastavit (Eclipse + QtPlugin / QtCreator) |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 14. září 2009, 22:38:20 Předmět: |
|
|
no, pokud je chces volat z pluginu, tak pretezovani je jasna cesta.
druha moznost je vyexportovat ty funkce ze spustitelne binarky, a potom ji prilinkovat k pluginu, nicmene si nejsem jisty jestli vubec linux umoznuje linkovat dynamicky spustitelnou binarku. (zkus,
gcc -l(jmeno originalniho spustitelneho souboru) plugin.cpp |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 15. září 2009, 01:53:47 Předmět: |
|
|
Kdysi jsem to řešil tak, že jsem měl (příklad:) jádro.so, které obsahovalo všechny hlavní funkce a při kompilaci pluginu jsem vždy použil parametr -ljádro, takže plugin věděl, kde ty funkce má hledat. V jádro.so jsem pak načetl pluginy (jejich seznam byl v externím souboru), loadovalo je přes dlopen a zavoláním nějaké hlavní funkce pluginu, jak to máš teď. jádro.so tedy otevřelo plugin.so, který díky parametru -ljádro věděl, kde ty funkce hledat. Tímto způsobem se obě dll používaly navzájem.
Nevýhoda tohoto přístupu je, že při změně jádro.so jsem musel rekompilovat pluginy, protože se mohlo změnit ABI (rozhraní zkompilované knihovny). Způsob přes virtuální metody je čistější, nemusíš linkovat plugin s jádro.so a includovat kompletní headery jádra, stačí jen interfacy, ale je potřeba ty interfacy dobře navrhnout už na začátku, protože při jejich změně budeš muset měnit věci na více místech zároveň, což není úplně košér. Lepší je samozřejmě ty interfacy neměnit vůbec, potom můžeš vyvíjet jádro i pluginy nezávisle na sobě.
Např. projekt Xorg téměř nezměnil základní interfacy několik dekád a vyvojáři dělali co mohli, aby to tak zůstalo i za cenu horší kvality kódu. Při jejich změně by se musely upravovat všechny knihovny a programy, které jej využívají, čímž by utrpěl celkový ekosystém kolem tohoto projektu. _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 15. září 2009, 08:15:45 Předmět: |
|
|
POUZI TO -rdynamic FUNGUJE TO
sorry ale mam to odskusane. virtualne metody pomozu taktiez kedze sa vytvory v-table v ktorej sa da najst dany symbol. -rdynamic spravy podobne pretoze prida vsetky symboli do dynamickej tabulky symbolov. _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 15. září 2009, 09:37:48 Předmět: |
|
|
Az prijdu domu tak pohledam jak bych to -rdynamic mohl pouzit. Mam projekt zalozeny na qmake, nemuzu prijit na to jak upravit parametry kompilace. |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 15. září 2009, 10:28:43 Předmět: |
|
|
nou napsal: |
POUZI TO -rdynamic FUNGUJE TO
sorry ale mam to odskusane. virtualne metody pomozu taktiez kedze sa vytvory v-table v ktorej sa da najst dany symbol. -rdynamic spravy podobne pretoze prida vsetky symboli do dynamickej tabulky symbolov. |
1) -rdynamic sem v man gcc nenasel
2) pokud funguje tak jak popisujes, tak je to ten nejdebilnejsi mozny zpusob jak poresit chybu v navrhu. |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 15. září 2009, 10:44:40 Předmět: |
|
|
mozno to v man gcc nie je pretoze to je volba pre linker.
man gcc napsal: |
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that
support it. This instructs the linker to add all symbols, not only
used ones, to the dynamic symbol table. This option is needed for
some uses of "dlopen" or to allow obtaining backtraces from within
a program. |
man dlopen napsal: |
If this program were in a file named "foo.c", you would build the program with the following command:
gcc -rdynamic -o foo foo.c -ldl |
man ld napsal: |
--export-dynamic
When creating a dynamically linked executable, add all symbols to the dynamic symbol table. The dynamic symbol table is the set of symbols which are visible from dynamic objects at run time.
If you do not use this option, the dynamic symbol table will normally contain only those symbols which are referenced by some dynamic object mentioned in the link.
If you use "dlopen" to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably need to use this option when linking the program itself. |
kde foo je hlavny program. nejdem sa hadat o tom ci je to chyba navrhu. ale pridavat virtual k metode mi zda hnusny hack. a prilinkovanie k pluginu ako popisuje Eosie ma tiez svoje nevyhody povedal by som este vetsie nez virtual.[/quote] _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 15. září 2009, 12:49:22 Předmět: |
|
|
Co je spatneho na tom co navrhoval Eoise? Jsem uvazoval ze bych si hlavni aplikaci rozdelil na casti, z kazde vytvoril "so" knihovnu, a k pluginu prilinkoval jen to co potrebuje tak by to fungovat melo, ne? |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 15. září 2009, 13:28:40 Předmět: |
|
|
Virtuální metody nejsou hack, je to vlastně to nejlepší, co můžete udělat a ulehčíte linkeru, protože, jak už jsem řekl, je to nejsnadnější způsob, jak vyvíjet projekt a jeho pluginy nezávisle na sobě a zachovat si kompatibilitu (mezi starým jádrem a novými pluginy, stejně jako mezi novým jádrem a starými pluginy).
Icek> Když nedokážeš napsat můj nick celý, piš jen "Eo". _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Icek
Založen: 29. 07. 2007 Příspěvky: 45 Bydliště: Banov 375
|
Zaslal: 15. září 2009, 13:57:36 Předmět: |
|
|
hehe chodim sem tak 5 let, celou tu dobu sem to cetl "eoise", tak sory
A jak je to s konstruktory? Ten virtualni neudelam... tou kompatibilitou myslis kompatibilitu ruznych verzi kompilatoru? nebo ceho? prece kdyz zmenim nazev volane metody tak je to v haji tak jako tak... |
|
Návrat nahoru |
|
 |
|