Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ kod iz shared liba kroz C interface

10 views
Skip to first unread message

Ermin Hasičević

unread,
Apr 15, 2012, 2:41:28 PM4/15/12
to

Dakle, poštovani auditorijume, možete vidjeti iz subjecta kakvu jebenu
situaciju imam. Poradi ograničenja compilera i linkera za propreitary
embedded OS koji imam mogu imati C++ kod unutar shared liba, ali
moram sa istim raditi kroz C interface.

Dakle ako imam u libu ovo:

class foo
{
...
void bar();
...
}

Kada hoću pozvati bar() iz nekog exea onda to mogu
ovako:

foo* _foo = create_foo();

...

foo_do_bar(_foo);

, a ne ovako:

_foo->bar();

Ima li itko kakav trik kako da na kraju odjebem ovaj foo_do_bar
i da mogu raditi kao čovjek sa C++ kodom iz shared liba koji
ima ovakva ograničenja?!

MelissA

unread,
Apr 15, 2012, 2:46:20 PM4/15/12
to
Postavlja se pitanje da li koristis isti kompajler i za lib
i za koricnicki kod?
Ocigledno je da C calling konvencija radi, ali ako imas
dva razlicita kompajlera mrka kapa onda.


Ermin Hasičević

unread,
Apr 15, 2012, 3:09:44 PM4/15/12
to MelissA
Da. Isti je i za korisnički kod i za lib. Kako mogu profitirati
od te činjenice?

Nisam baš objasnio stvar do kraja. Ovaj compiler/linker
od proprietary OS-a koriste compiler/linker iz ovog paketa:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.swdev.rvds/index.html


Ermin Hasičević

unread,
Apr 15, 2012, 3:09:55 PM4/15/12
to
On 4/15/2012 8:46 PM, MelissA wrote:

MelissA

unread,
Apr 15, 2012, 3:14:48 PM4/15/12
to
On Sun, 15 Apr 2012 21:09:44 +0200
Pa onda mozes napisati _foo->bar(); bez problema.
Ukoliko je sa korisnicke strane takodje isti c++ kompajler.
Fora je samo da brisanje i kreiranje objekata moras
preko C interfejsa ukoliko dinamicki iz koda ucitavas shared
lib. E sad proslo bi i brisanje ukoliko shared
lib koristi istu rutinu/heap, ali da budes sa sigurne
strane brisi objekt preko c f-je.

Ermin Hasičević

unread,
Apr 15, 2012, 4:04:16 PM4/15/12
to
I ja sam mislio da je dovoljno samo pozivati create_foo
i destroy_foo, a onda u (C++) aplikaciji radim sa foo normalno
tj. po C++ konvenciji, ali to ne ide. Bar ne bez neke voodoo
magije. Ili te nisam dobro shvatio što mi želiš kazati?!

Goran Mitrovic

unread,
Apr 15, 2012, 4:54:10 PM4/15/12
to
On Sun, 15 Apr 2012 20:41:28 +0200, Ermin Hasi?evi?
<ime.p...@gmail.com> wrote:

>
>Dakle, poštovani auditorijume, možete vidjeti iz subjecta kakvu jebenu
>situaciju imam. Poradi ograni?enja compilera i linkera za propreitary
>embedded OS koji imam mogu imati C++ kod unutar shared liba, ali
>moram sa istim raditi kroz C interface.
>
>Dakle ako imam u libu ovo:
>
>class foo
>{
>...
> void bar();
>...
>}
>
>Kada ho?u pozvati bar() iz nekog exea onda to mogu
>ovako:
>
>foo* _foo = create_foo();
>
>...
>
>foo_do_bar(_foo);
>
>, a ne ovako:
>
>_foo->bar();
>
>Ima li itko kakav trik kako da na kraju odjebem ovaj foo_do_bar
>i da mogu raditi kao ?ovjek sa C++ kodom iz shared liba koji
>ima ovakva ograni?enja?!

Unaprijed se ispricavam jer nisam najpazljivije procitao, ali...

Daklem, nemoj eksportirat metode klase, vec definiraj baznu klasu i sve
cemu pristupas proglasi virtualnim. U tom slucaju sve prebacujes na
kompajler, a ne linker.


U includeu:

class Iaa
{
public:
virtual bb() = 0;
};

Iaa *create_aa();
void destroy_aa(Iaa *);


U shared libu:

class aa : public Iaa {...};

Iaa*create_aa() {return new aa();}
void destroy_aa...


U glavnom programu:

Iaa *a = create_aa();
a->bb();


Ovisno o ogranicenjima, eventualno ovaj Iaa * pretvori u void *, pa
castaj.

Ivan Popovski

unread,
Apr 16, 2012, 9:03:29 AM4/16/12
to
> magije. Ili te nisam dobro shvatio ??to mi ??eli?? kazati?!

Nisam bas pazljivo pratio, ali postoji nesto sto se zove POD (plain old data)
i mozda ti moze pomoci:

http://en.wikipedia.org/wiki/Plain_old_data_structure
http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.7

Bile su neke izmjene kod novog standarda, ali ono.

Ermin Hasicevic

unread,
Apr 18, 2012, 10:17:40 AM4/18/12
to
Tnx, stvar radi odlicno! :) No i dalje ne znam sto znaci da ovim sve
prebacujem na
compiler?! Zanima me objasnjenje tog fenomena pa ako ti se da
objasnit, možeš
li opisati to u nekoliko kratkih crta ili dati neki link?

Ermin Hasicevic

unread,
Apr 18, 2012, 10:20:03 AM4/18/12
to
On Apr 16, 3:03 pm, Ivan Popovski <viviv...@nj.g> wrote:
> On 2012-04-15, Ermin Hasi??evi?? <ime.prez...@gmail.com> wrote:
>
> > On 4/15/2012 9:14 PM, MelissA wrote:
> >> Pa onda mozes napisati _foo->bar(); bez problema.
> >> Ukoliko je sa korisnicke strane takodje isti c++ kompajler.
> >> Fora je samo da brisanje i kreiranje objekata moras
> >> preko C interfejsa ukoliko dinamicki iz koda ucitavas shared
> >> lib. E sad proslo bi i brisanje ukoliko shared
> >> lib koristi istu rutinu/heap, ali da budes sa sigurne
> >> strane brisi objekt preko c f-je.
>
> > I ja sam mislio da je dovoljno samo pozivati create_foo
> > i destroy_foo, a onda u (C++) aplikaciji radim sa foo normalno
> > tj. po C++ konvenciji, ali to ne ide. Bar ne bez neke voodoo
> > magije. Ili te nisam dobro shvatio ??to mi ??eli?? kazati?!
>
> Nisam bas pazljivo pratio, ali postoji nesto sto se zove POD (plain old data)
> i mozda ti moze pomoci:
>
> http://en.wikipedia.org/wiki/Plain_old_data_structurehttp://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.htmlhttp://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.7
>
> Bile su neke izmjene kod novog standarda, ali ono.

Hvala na prijedlogu, ali Goranovo riješenje mi je OK. Ovo mi je malo
too much Cish. ;)

Goran Mitrovic

unread,
Apr 18, 2012, 11:04:44 AM4/18/12
to
On Wed, 18 Apr 2012 07:17:40 -0700 (PDT), Ermin Hasicevic
<ermin.h...@gmail.com> wrote:

>> Daklem, nemoj eksportirat metode klase, vec definiraj baznu klasu i sve
>> cemu pristupas proglasi virtualnim. U tom slucaju sve prebacujes na
>> kompajler, a ne linker.
>>
>
>Tnx, stvar radi odlicno! :) No i dalje ne znam sto znaci da ovim sve
>prebacujem na
>compiler?! Zanima me objasnjenje tog fenomena pa ako ti se da
>objasnit, možeš
>li opisati to u nekoliko kratkih crta ili dati neki link?

Eh, ne znam koliko cu uspjeti suvislo objasniti, no, pokusat cu...



Dakle, u originalnom slucaju, tvoj .lib fajl interno sadrzi tablicu svojih
eksportiranih funkcija gdje povezuje ime funkcije sa adresom gdje se ona u
libu nalazi.

U exeu to koristis tako da napravis extern <potpis funkcije> cime dajes do
znanja kompajleru kakva je funkcija i da je definirana negdje drugdje. Kad
dodje do linkanja, linker ce sve to posloziti; konkretno, tu funkciju nece
pronaci u exeu, pa ce ici po libovima, pronaci ime u tablici i tamo ce
saznati adresu s kojom treba poziv funkcije povezati.

To sto konkretno imas member funkciju, a ne globalnu, uopce nije bitno -
vrijede identicna pravila.



U 'mom' slucaju, sa virtualnim funkcijama, library ne eksportira nista,
vec samo priredi objekt sa tocno propisanim layoutom (tocno se zna kako
treba posloziti u memoriji member varijable, te vtable - tablicu sa
pointerima na virtualne funkcije).

Na strani exe-a kompajler isparsira include fajl i time dozna layout
klase. S obzirom da to zna, kad mu prebacis pointer na klasu i pozoves
funkciju, on zna doci do vtablea, zna na kojem se offsetu nalazi pozvana
funkcija i automatski moze procitati na koju adresu treba skociti. U
teoriji radi se o jednom koraku vise, ali, sve se odvije bez pomoci
linkera i bez potrebe da moduli izmjenjuju imena funkcija.



P.S. Za ispravne termine koje treba guglat ce vec netko drugi pomoci.
Mozda static i dynamic/virtual binding? Npr, na testu za trenutno posao
nisam znao odgovoriti sto je to enkapsulacija, a nije da je ne trosim
svaki dan. ;)

Ermin Hasičević

unread,
Apr 19, 2012, 5:13:21 PM4/19/12
to
OK. :) In a meantime ... pretpostavljam da overhead u %-ima nije
značajan ni što se tiče brzine ni veličine?

Ima li neki zgodan način da upakiram create i destroy funkcije
za pointere objekata u opticaju?

Goran Mitrovic

unread,
Apr 19, 2012, 6:08:40 PM4/19/12
to
>zna?ajan ni što se ti?e brzine ni veli?ine?

Ako funkcija koju zoves ima vise od nula linija koda, neces moci izmjeriti
usporenje.


>Ima li neki zgodan na?in da upakiram create i destroy funkcije
>za pointere objekata u opticaju?

Ako mi nesto drugo ne bi palo na pamet, ja bi to otprilike ovako, sa
makroima i templateovima, sto otprilike znaci da se nikome drugome nece
svidjeti... ;)


u headeru:

#include "c_class.h"

class aa {
...
};
C_CLASS(aa)



u libu:

#define C_CLASS_IMPL
#include "c_class.h"



u exeu:

aa_t aa = new_aa();

(aa_t je shared_ptr)


novi header c_class.h:

#ifndef C_CLASS_IMPL
# define C_CLASS(name)\
name *create_##name();\
void destroy_##name(name *);\
typedef std::shared_ptr<name> name##_t;\
inline name##_t new_##name() {return
std::shared_ptr(create_##name(), destroy_##name);}
#else
# define C_CLASS(name)\
name *create_##name() {return new name;}\
void destroy_##name(name *n) {delete n;}
#endif


P.S. Ako ti konstruktori imaju parametre, bolje zaboravi na automatiku...
0 new messages