Aloitin C++ -ohjelmoinnin. Alustana on Ubuntu 10.04 ja käytän tekstieditoria ja komentorivikääntäjää g++.
Tarvitsen projektiin valmiin koodin joka sattuu olemaan C-kielinen. Mieleen tuli muutama vaihtoehto:
1. linkittää gcc:llä käännetty c-koodi ja g++:lla käännetty keskenään normaaliin tapaan g++:lla
2. kääntää jollain vehkeellä c-lähdekoodi c++-lähdekoodiksi
3. tehdä c-kielisestä osasta shared object library ja käyttää sitä
Vaihtoehtoa 2 en heti taida kokeilla, koska olen sen verran aloittelija c++:ssa ja c:tä en osaa senkään vertaa.
Tein pienen testiprojektin jolla olen kokeillut toisia vaihtoehtoja. 1 ei toiminut - ilmeisesti se ei voikaan toimia vai kuinka? 3. vaihtoehto pitäisi toimia tämän mukaan:
Ja täällä on selvät ohjeet .so -kirjaston tekoon:
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
Testiprojektini:
sub.c
int getvalue(arg) const int arg; { return arg + 1; }
main.cpp
#include <iostream> int getvalue(int); int main() { const int num = 5; int result = getvalue(num); std::cout << result << std::endl; }
gcc -Wall -fPIC -c sub.c
gcc -shared -Wl,-soname,libsubtest.so.1 -o libsubtest.so.1.0 sub.o
sudo mv libsubtest.so.1.0 /opt/lib
sudo ln -sf /opt/lib/libsubtest.so.1.0 /opt/lib/libsubtest.so.1
sudo ln -sf /opt/lib/libsubtest.so.1.0 /opt/lib/libsubtest.so
Kaikki näytti hyvältä, ei varoituksia, ja ne .so-tiedostot on siellä /opt/lib:ssä.
g++ -Wall -L/opt/lib main.cpp -lsubtest -o the-program
->
/tmp/cc4zcgK7.o: In function `main':
main.cpp:(.text+0x19): undefined reference to `getvalue(int)'
collect2: ld returned 1 exit status
Missä vika?
Jos olisit malttanut lukea C++-opasta, tietäisit tämänkin:
Opas kirjoitti:
Vastaavasti kun C++-koodissa käytetään C:llä tehtyjä funktioita, täytyy käyttää samaista extern "C" -määrettä.
C++:ssa luokkien ja nimiavaruuksien ja function overloadingin (suomenkielinen termi?) takia funktioiden nimiin laitettava tieto parametrien ja paluuarvon tyypeistä (aka name mangling). C:ssä tätä tilannetta ei ole. Sunin C++-kääntäjä tuottaa tuosta määrittelystä (korjatulla parametrin tyypillä tosin) nimen __1cIgetvalue6Fki_i_. Name manglingista pääsee C++:ssa eroon määritteellä extern "C".
Funktioiden forward declarationeista parametrien nimien pudottamista ei monasti pidetä kovin hyvänä tapana, joten suosittelisin siitä luopumista, jos ei ole mitään suurempaa syytä tähän käytäntöön, kuten muotoilusääntöjä, joita on pakko noudattaa. Samaa voisi sanoa vanhan tyylisistä funktioiden määrittelyistä C:ssä.
EDIT: Jaaha, Metabolix ninjaili sillä aikaa ohitse, kun tämä vain roikkui taustavälilehdessä.
Kiitoksia vastauksista! Joo enpä sitten ollut malttanut tuota kohtaa lukea... Hyvin toimii nyt, ja myös ihan näin:
gcc -c sub.c
g++ -c main.cpp
g++ *.o
eli .so-kirjastoa ei tämän takia tarvitsekaan tehdä.
fronty kirjoitti:
Funktioiden forward declarationeista parametrien nimien pudottamista ei monasti pidetä kovin hyvänä tapana, joten suosittelisin siitä luopumista, jos ei ole mitään suurempaa syytä tähän käytäntöön
Ok, eipä tuohon mitään syytä ole. Selkeämpihän se on jos ne parametrien nimet näkyy siinä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.