Keresek valakit, aki már csinált olyat, hogy egy PHP-s program(rendszer)hez SWIG révén C-s, C++-os modult készített. Egy konkrét példa lenne a logaritmikus keresés megvalósítása C(++) modulként. Egy szájbarágó dokumentáció is felvidítana.
- 1578 megtekintés
Hozzászólások
subscribe
- A hozzászóláshoz be kell jelentkezni
Csak hírtelen rákerestem, kiváncsi voltam mit találok, nekem (aki nem próbálkozott ilyennel) jónak tűnik:
http://www.swig.org/tutorial.html -> az interface fájl elkészítéséhez talán ez is elég!
http://www.swig.org/Doc1.3/Php.html -> utána szinte lépésről-lépésre
- A hozzászóláshoz be kell jelentkezni
Kipróbáltam a tutorial-beli legegyszerűbb példát, le is fordult, de a php5-öm nem tudta megemészteni a keletkezett kiterjesztést.
Nincs most előttem a konkrét hibaüzenet, de valami szintaktikai hiba volt. Ubuntu 9.4-esen és SWIG 1.3.x-en próbáltam (a hivatalos Ubuntu csomaggal). Továbbra is keresek valakit, aki próbált már ilyet csinálni élesben.
- A hozzászóláshoz be kell jelentkezni
Szia, remélem lesz valaki aki tényleg csinált ilyet :-) egy "UP"-ra jó vagyok!
Attila, Perger
-----------------------------------------------------
"Az a szoftver, amelyiket nem fejlesztik, az halott!"
- A hozzászóláshoz be kell jelentkezni
Ez lett a hibaüzenet: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20060613/example.so' - /usr/lib/php5/20060613/example.so: undefined symbol: Foo in Unknown on line 0
Egyébként ez volt a kiindulási example.c fájl:
/* File : example.c */
#include
/* A global variable */
double Foo = 3.0;
void print_Foo() {
printf("In C, Foo = %f\n",Foo);
}
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
- A hozzászóláshoz be kell jelentkezni
Hali! Egy ilyen .i fájllal működik:
%module example
%{
extern double Foo;
extern void print_Foo();
extern int gcd( int x, int y );
%}
extern double Foo;
extern void print_Foo();
extern int gcd( int x, int y );
A [/code]module example[code] rész kerül bele a wrapper C-be. Így hiszi el a fordító, hogy lesz majd - legkésőbb linkelésnél - valamelyik modulban egy ilyen változó, ilyen függvény, stb.
A függvényfejlécek elől talán elhagyható az extern, mert azok úgyis csak fejlécek. A változóknál viszont kell.
Ha több modulban van ugyanaz a változó (extern nélkül), az linkelési hiba (ezért .h-ba se szoktunk változót rakni). Ha egyikben sincs, mindenhol csak extern van, az is linkelési hiba (szerintem Nálad ez történt).
- A hozzászóláshoz be kell jelentkezni
Igen, igazad volt, köszi! Ezzel az .i fájlal megy! Az 'eredeti' - ami egyébként a swig-examples csomagban volt - nem volt jó.
- A hozzászóláshoz be kell jelentkezni
szz barátommal közben magánban beszéltünk, sikerült megoldani. :-)
Néhány észrevétel:
* Fontos fordításnál az -fpic paraméter, ha .so-k lesznek belőle.
* Nem minden doksi írta le, hogy a modult és a wrappert össze kell linkelni.
* Érdemes nézni az apacs hibanaplóját modul betöltésekor, ott nagyon sok minden kiderülhet.
* Érdemes nézni a phpinfo()-t, hogy betöltődött-e a modul.
Folyamat:
- zend API telepítése (Debianban php5-dev; az kell, amiben pl. a zend.h benne van)
- SWIG telepítése
- Érdemes egy Makefile-t írni, ami a wrapper-t generálja, elvégzi a két fordítást és a linkelést.
- C(++)-modul megírása
- interfészfájl megírása
- wrapper generálása
# swig -php interfész.i
Úgy látom, szól, ha valami hiba van. Ha nincs, előállítja a wrappert a Zend-hez, meg a PHP-include-ot.
- modul lefordítása
# gcc -fpic -Wall -o proba.o -c proba.c
- wrapper lefordítása
# gcc `php-config --includes` -fpic -Wall -o proba_wrap.o -c proba_wrap.c
- Csatoljuk a kettőt, ráadásul dinamikus .so-t linkelünk belőle
# gcc -shared -o proba.so proba.o proba_wrap.o
- Ezt a proba.so-t el kell helyezni oda, ahol a PHP megtalálja. Ez kész csomagokra nálam az /usr/lib/php5/20090626+lfs könyvtár, de én szívem szerint az /usr/local/lib/php5 alá teszem, amíg nem csinálok belőle .deb-csomagot, ekkor viszont a komplett útvonalat meg kell majd adni a konfigban, a következő lépésben.
- php-nak mondjuk meg, hogy van egy ilyen kiterjesztés. A php.ini nálam már darabolt, azaz /etc/php5/apache2/ini-ben való turkálás helyett már csinálhatok egy /etc/php5/conf.d/proba.ini fájlt. Ebbe az előzőek alapján útvonallal együtt:
extension=/usr/local/lib/php5/proba.so
- Apache újratöltése, pl.:
# tail -f /var/log/apache2/error.log
ENTER, ENTER, hogy tisztábban lássunk. :-)
Másik terminálon:
# /etc/inti.d/apache2 reload
No, itt a hibanaplóban fog megjelenni, hogy pl. nem találja a .so-t; találja, de nem definiáltál egy címkét (változót, függvényt, stb.); merthogy most történik meg a linkelés dinamikusan.
Ha szimbólumokkal kapcsolatos, vagy más linkelési hiba van, javítani kell a C-fájlt, vagy az interfészt, és onnan elölről... ha van Makefile, a make parancs pontosan azt gyártja újra, amit változáskor kell.
- Nézzünk PHP-ban egy phpinfo()-t. A modul nevére rákeresve ott kell legyen a kimeneten. :-)
Ha ez is jó volt, akkor már nekem működtek a függvények.
- A hozzászóláshoz be kell jelentkezni
Köszi, Kübi, a remek összefoglalót! Sokan hasznát veszik!!
- A hozzászóláshoz be kell jelentkezni