.[ ČeskéHry.cz ].
Pluginy
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
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

PříspěvekZaslal: 14. září 2009, 19:04:59    Předmět: Pluginy Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
pcmaster



Založen: 28. 07. 2007
Příspěvky: 1827

PříspěvekZaslal: 14. září 2009, 19:45:08    Předmět: Odpovědět s citátem

No podla toho chyboveho hlasenia typujem, ze trieda Project sa nenachadza v Scope tvojej funkcie Test? Smile 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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Icek



Založen: 29. 07. 2007
Příspěvky: 45
Bydliště: Banov 375

PříspěvekZaslal: 14. září 2009, 19:55:34    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 14. září 2009, 20:11:50    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Yossarian



Založen: 28. 07. 2007
Příspěvky: 274
Bydliště: Šalingrad

PříspěvekZaslal: 14. září 2009, 21:20:58    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Icek



Založen: 29. 07. 2007
Příspěvky: 45
Bydliště: Banov 375

PříspěvekZaslal: 14. září 2009, 21:54:02    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Yossarian



Založen: 28. 07. 2007
Příspěvky: 274
Bydliště: Šalingrad

PříspěvekZaslal: 14. září 2009, 22:38:20    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 15. září 2009, 01:53:47    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 15. září 2009, 08:15:45    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Icek



Založen: 29. 07. 2007
Příspěvky: 45
Bydliště: Banov 375

PříspěvekZaslal: 15. září 2009, 09:37:48    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Yossarian



Založen: 28. 07. 2007
Příspěvky: 274
Bydliště: Šalingrad

PříspěvekZaslal: 15. září 2009, 10:28:43    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 15. září 2009, 10:44:40    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Icek



Založen: 29. 07. 2007
Příspěvky: 45
Bydliště: Banov 375

PříspěvekZaslal: 15. září 2009, 12:49:22    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 15. září 2009, 13:28:40    Předmět: Odpovědět s citátem

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
Zobrazit informace o autorovi Odeslat soukromou zprávu
Icek



Založen: 29. 07. 2007
Příspěvky: 45
Bydliště: Banov 375

PříspěvekZaslal: 15. září 2009, 13:57:36    Předmět: Odpovědět s citátem

hehe Smile 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
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna