Udv,
Van egy C++-ban irt .dll aminek a fuggvenyeit Python-bol kellene meghivnom. Hogyan tudnam Python-bol hasznalni a kovetkezo szignaturaju fuggvenyt?:
int func (char **);
Az alabbi mukodik, de itt ugye csak char * es nem char ** van:
GetDeviceName = Debug.GetDeviceName
Debug_GetDeviceName.restype = c_int
Debug_GetDeviceName.argtypes = [c_char_p]
status = SiDebug_GetDeviceName(name)
Koszi,
/sza2
- 3793 megtekintés
Hozzászólások
Írj a Python és a DLL közé egy wrappert.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Ez egy kicsit bovebben jobb lenne:-)
Ugy erted, C/C++ ban? - Akkor ugy erzem, vegig kellene vezetnem a tobb tiz fuggvenyt a wrapper-en.
Nincs erre valami altalanosan elfogadott megoldas? Vegulis ez egy 2 dimenzios tomb, jelen esetben 0-val vegzodo karakterlancok tombje, kb. mint 'argv'.
Nem tudom ezt valahogy egyszeruen kinyerni Python-ban?
/sza2
- A hozzászóláshoz be kell jelentkezni
> Ez egy kicsit bovebben jobb lenne:-)
http://docs.python.org/extending/extending.html
> Vegulis ez egy 2 dimenzios tomb
Ezt csak te tudod, a C forditonak (es a Pythonnak is) egy pointer (char*) tipusra. Ami mellesleg lehet tomb is akar, de ez egyatalan nem biztos.
- A hozzászóláshoz be kell jelentkezni
Pythonból még nem hívtam bele DLL-be (C#-ból viszont szoktam), szóval kicsit általános lesz a hozzászólásom.
Írj egy DLL-t, amiből helyesen meg tudod hívni az eredeti DLL függvényeit (és persze teszteld is le), de úgy, hogy a köztes DLL függvényeit könnyen meg tudd hívni Pythonból. A fekete mágia részét (pointer -> pointerre mutató pointer) pedig a köztes (wrapper) DLL-ben oldd meg.
Műszaki ember rajzból ért:
Python -> Wrapper -> eredeti DLL
Jobb megoldás most nem jut eszembe.
Viszont ha sikerül, oszd meg velünk is, mert a hasonló topikikat megtalálja a Google is :-) Hátha valamikor másnál is előkerül ugyanez a dolog.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Még nem használtam, de innen indulnék el:
http://docs.python.org/library/ctypes.html
- A hozzászóláshoz be kell jelentkezni
Használj swig-et, ha nem csak egy-két függvényről van szó.
- A hozzászóláshoz be kell jelentkezni
Alapvetően két lehetőséged van:
Az első amivel ha jól látom most próbálkozol, a ctypes-os megoldás. Most hirtelen elolvasva a dokumentációt én sem látom, hogy tudnád megoldani ezzel.
A második lehetőség valamilyen wrapper írása.
Ezen belül viszont megint két lehetőséged van:
1) Írsz egy ctype barát wrappert C-ben és küzdesz azzal
2) Írsz egy rendes Python modult.
Az első egy kicsit csúnya, és nem biztos hogy gyors megoldáshoz vezet.
A 2) esetében megint egy rakás választásod van:
a) Megírod a wrapper modult C-ben ahogy írva vagyon itt.
b) Megírod a wrapper modult C++-ban ahogy írva vagyon itt. (Boost python)
c) Generálod a wrappert ahogy írva vagyon itt. (SWIG)
d) Megírod a wrapper modult python+C-ben ahogy írva vagyon itt. (Cython/Pyrex)
Az a) nekem macerásnak tűnik, ha nem csináltál még ilyet.
A b) igen egyszerű és gyors megoldás, ha van C++ gyakorlatod és a Boost kéznél van. (Egyéb esetben nem ajánlom, hogy belekezdj.)
A c)-ről nincs személyes tapasztalatom, de egyrészt ágyúval verébre, másrészt nem az egyszerűségéről híres
A d)-vel van tapasztalatom, bár nem erre használtam, csak optimalizációra. Arra nagyon kényelmes volt, gyanítom ez sem okozhat vele problémát.
Én személy szerint a b) és d) közül választanék attól függően, hogy mennyire komplex wrappert akarok használni.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Swig-et használva mondjuk nagy az esélye, hogy nem kell C/C++-ban programozni, csak a swig-et kell megismerni kicsit. Mint utaltam rá korábban, 1-2 funkciónál nem jön elő az előnye, de kicsit több funkció, osztály, stb. használata esetén már komoly időmegtakarítás, kevesebb hibalehetőség, jobb karbantarthatóság, stb.
Az egyszerűséggel kapcsolatban nem tudom mi a gond, a többi általad felsorolt megoldás is legalább hasonló bonyolultságú, mint a swig-es, sőt...
- A hozzászóláshoz be kell jelentkezni
"Swig-et használva mondjuk nagy az esélye, hogy nem kell C/C++-ban programozni, csak a swig-et kell megismerni kicsit."
És ez pont a legnagyobb hátránya, mivel ha valaki python-ból hívogat C fv-eket, akkor feltételezhetjük, hogy két dolgot ismer valamennyire: a pythont és a C-t. :)
De még ha ez nem is igaz, az tény, hogy egy olyan új "nyelvet" kell megtanulni amit egyébként nem használ az ember másra.
Ez mondjuk igaz a cython-ra is, bár szerintem egy python fejlesztőnek az elég hasznos tud lenni.
A bonyolultságról meg annyit, hogy a swig-es tutorial alapján gyakorlatilag esélytelen a fentebb vázolt string tömbös fv használata, sőt ez alapján még azt is megkockáztatom, hogy lehetetlen. (Ugyan sza2king nem fogalmaz egyértelműen, de nekem a char** parameter output paraméternek tőnik...)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
"Reménykedtem", hogy nem a kérdező az első ember a földön, aki ilyesmit akar megoldani swiggel... ;)
1 perc swig doksiban keresgélés után a a megoldás: Converting Python list to a char **
Copy paste, és egy parancs futtatása után kész a wrapper - ennél egyszerűbb nem tudom mi tud lenni, hozzá se kell szagolni a C részhez.
Az új nyelv az kb. 5 darab direktíva.
De nem hit térítek tovább.
- A hozzászóláshoz be kell jelentkezni
Ez momentán semmivel nem egyszerűbb mint bármelyik másik, és konkrétan a python C API-t használja, szóval nem igaz, hogy nem kell a C-hez hozzászagolni.
Persze nyilván egyszerű lenne a copy-paste, de az én értelmezésem szerint a fordított irány kell a kedves kérdezőnek (char** -> Python list).
Mondjuk nem úgy néz ki mint akit érdekelnek a válaszok, szóval részemről én is befejeztem. :)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Újabban van még egy e) lehetőség is, a Shiboken. Azt nem tudom, hogy mik az előnyei/hátrányai a többihez képest.
- A hozzászóláshoz be kell jelentkezni
Subs, annak idején ezért hagytam ott a PyQt4-et.
- A hozzászóláshoz be kell jelentkezni