Mercurial > pub > dyncall > bindings
changeset 16:a40084782546
- added support for more return values to python binding
- python binding readme update
author | cslag |
---|---|
date | Sat, 26 Mar 2016 22:31:42 +0100 |
parents | 1673ab696715 |
children | 739c40f35a6a |
files | python/pydc/README.txt python/pydc/pydcext.c |
diffstat | 2 files changed, 82 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/python/pydc/README.txt Sat Mar 26 16:09:41 2016 +0100 +++ b/python/pydc/README.txt Sat Mar 26 22:31:42 2016 +0100 @@ -1,21 +1,24 @@ dyncall python bindings -(C) 2007-2016 Daniel Adler. +(C) 2007-2016 Daniel Adler Dec 4, 2007: initial -Mar 22,2016: brought up to dyncall 0.9 +Mar 22,2016: update to dyncall 0.9, includes breaking sig char changes BUILD/INSTALLATION ------------------- +================== 1) make sure dyncall is built and libraries/headers are in include paths or CFLAGS points to them, etc. 2) Build and install this extension with: - python setup.py install + + python setup.py install + +Building an egg isn't supported, currently. API ---- +=== libhandle = load(libpath) funcptr = find(libhandle, symbolname) @@ -23,42 +26,43 @@ SIGNATURE FORMAT ----------------- +================ is a formated string format: "xxxxx)y" - x is positional parameter-type charcode - - 'B' C++: bool <- Python: PyBool - 'c' C: char <- Python: PyInt (range checked) - 's' C: short <- Python: PyInt (range checked) - 'i' C: int <- Python: PyInt - 'j' C: long <- Python: PyLong - 'l' C: long long <- Python: PyLongLong - 'f' C: float <- Python: PyFloat (cast to single precision) - 'd' C: double <- Python: PyFloat - 'p' C: void* <- Python: PyCObject - 'Z' C: const char* <- Python: PyString + x is positional parameter-type charcode, y is result-type charcode - y is result-type charcode + SIG | FROM PYTHON | C/C++ | TO PYTHON + ----+------------------------------------+--------------------+----------------------------------- + 'v' | | void | + 'B' | PyBool | bool | PyBool + 'c' | PyInt (range checked) | char | PyInt + 'C' | PyInt (range checked) | unsigned char | PyInt + 's' | PyInt (range checked) | short | PyInt + 'S' | PyInt (range checked) | unsigned short | PyInt + 'i' | PyInt | int | PyInt + 'I' | PyInt | unsigned int | PyInt + 'j' | PyLong | long | PyLong + 'J' | PyLong | unsigned long | PyLong + 'l' | PyLongLong | long long | PyLongLong + 'L' | PyLongLong | unsigned long long | PyLongLong + 'f' | PyFloat (cast to single precision) | float | PyFloat (cast to double precision) + 'd' | PyFloat | double | PyFloat + 'p' | PyCObject | void* | PyCObject encapsulating a void* + 'Z' | PyString | const char* | PyString - 'v' C: void - 'B' C++: bool -> Python: PyBool - 'c' C: char -> Python: PyInt - 's' C: short -> Python: PyInt - 'i' C: int -> Python: PyInt - 'j' C: long -> Python: PyLong - 'l' C: long long -> Python: PyLongLong - 'f' C: float -> Python: PyFloat (cast to double precision) - 'd' C: double -> Python: PyFloat - 'p' C: ptr -> Python: PyCObject encapsulating a void* - 'Z' C: const char* -> Python: PyString + +TODO +==== + +- support signature suffixes used to indicate calling conventions, are not supported yet! +- not sure if returning 'p' is working, creating PyCObject, check and write test code BUGS ----- +==== * build on osx/ppc - link error i386 something... [MacPython 2.4]
--- a/python/pydc/pydcext.c Sat Mar 26 16:09:41 2016 +0100 +++ b/python/pydc/pydcext.c Sat Mar 26 22:31:42 2016 +0100 @@ -15,7 +15,7 @@ /* PyCObject destructor callback for libhandle */ -void free_library(void* libhandle) +void free_library(void* libhandle) { if (libhandle != 0) dlFreeLibrary(libhandle); @@ -49,13 +49,13 @@ void* funcptr; if ( !PyArg_ParseTuple(args,"Os", &pcobj, &symbol) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); - + libhandle = PyCObject_AsVoidPtr(pcobj); - + if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is null"); funcptr = dlFindSymbol(libhandle, symbol); - if (!funcptr) + if (!funcptr) return PyErr_Format(PyExc_RuntimeError, "symbol '%s' not found", symbol); return PyCObject_FromVoidPtr(funcptr, NULL); @@ -70,9 +70,9 @@ void* libhandle; if ( !PyArg_ParseTuple(args,"o", &pcobj) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); - + libhandle = PyCObject_AsVoidPtr(pcobj); - + if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is NULL"); dlFreeLibrary(libhandle); @@ -98,18 +98,18 @@ char ch; int pos; void* pfunc; - + if ( !PyArg_ParseTuple(in_args,"OsO", &pcobj_funcptr, &signature, &args) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); - pfunc = PyCObject_AsVoidPtr(pcobj_funcptr); + pfunc = PyCObject_AsVoidPtr(pcobj_funcptr); if ( !pfunc ) return PyErr_Format( PyExc_RuntimeError, "function pointer is NULL" ); l = PyTuple_Size(args); ptr = signature; - pos = 0; + pos = 0; dcReset(gpCall); - - while ( (ch = *ptr) != '\0' && ch != ')' ) + + while ( (ch = *ptr) != '\0' && ch != ')' ) { PyObject* po; @@ -119,17 +119,18 @@ po = PyTuple_GetItem(args,pos); - switch(ch) + switch(ch) { case DC_SIGCHAR_BOOL: { DCbool b; - if ( !PyBool_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a bool", index ); + if ( !PyBool_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a bool", index ); b = (Py_True == po) ? DC_TRUE : DC_FALSE; dcArgBool(gpCall, b); } break; case DC_SIGCHAR_CHAR: + case DC_SIGCHAR_UCHAR: { DCchar c; if ( PyString_Check(po) ) @@ -138,51 +139,55 @@ size_t l; char* s; l = PyString_GET_SIZE(po); - if (l != 1) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string with length of 1 (a char string)", index ); - s = PyString_AsString(po); + if (l != 1) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string with length of 1 (a char string)", index ); + s = PyString_AsString(po); c = (DCchar) s[0]; } - else if ( PyInt_Check(po) ) + else if ( PyInt_Check(po) ) { long l; l = PyInt_AsLong(po); if ( (l > CHAR_MAX) || (l < CHAR_MIN)) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a char code", index ); c = (DCchar) l; } - else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index ); + else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index ); dcArgChar(gpCall, c); } break; case DC_SIGCHAR_SHORT: + case DC_SIGCHAR_USHORT: { DCshort s; long v; if ( !PyInt_Check(po) ) - return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index ); + return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index ); v = PyInt_AS_LONG(po); - if ( (v < SHRT_MIN) || (v > SHRT_MAX) ) + if ( (v < SHRT_MIN) || (v > SHRT_MAX) ) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a short value", index ); s = (DCshort) v; dcArgShort(gpCall, s); - } + } break; case DC_SIGCHAR_INT: + case DC_SIGCHAR_UINT: { long v; - if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); + if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); v = PyInt_AS_LONG(po); dcArgInt(gpCall, (DCint) v ); } break; case DC_SIGCHAR_LONG: + case DC_SIGCHAR_ULONG: { long v; - if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); + if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); v = PyInt_AsLong(po); - + } break; case DC_SIGCHAR_LONGLONG: + case DC_SIGCHAR_ULONGLONG: { PY_LONG_LONG pl; DClonglong dl; @@ -205,7 +210,7 @@ double d; if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); d = PyFloat_AsDouble(po); - dcArgDouble(gpCall, d); + dcArgDouble(gpCall, d); } break; case DC_SIGCHAR_POINTER: @@ -242,17 +247,25 @@ ch = *++ptr; - switch(ch) + switch(ch) { - case DC_SIGCHAR_VOID: dcCallVoid (gpCall, pfunc); Py_RETURN_NONE; - case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool (gpCall, pfunc)); - case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt (gpCall, pfunc)); - case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", (unsigned long long)dcCallLongLong(gpCall, pfunc)); - case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat (gpCall, pfunc)); - case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble (gpCall, pfunc)); - case DC_SIGCHAR_STRING: return Py_BuildValue("s", dcCallPointer (gpCall, pfunc)); - case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer (gpCall, pfunc)); - default: return PyErr_Format( PyExc_RuntimeError, "invalid return type signature"); + case DC_SIGCHAR_VOID: dcCallVoid (gpCall, pfunc); Py_RETURN_NONE; + case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool (gpCall, pfunc)); + case DC_SIGCHAR_CHAR: return Py_BuildValue("b", dcCallChar (gpCall, pfunc)); + case DC_SIGCHAR_UCHAR: return Py_BuildValue("B", dcCallChar (gpCall, pfunc)); + case DC_SIGCHAR_SHORT: return Py_BuildValue("h", dcCallShort (gpCall, pfunc)); + case DC_SIGCHAR_USHORT: return Py_BuildValue("H", dcCallShort (gpCall, pfunc)); + case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt (gpCall, pfunc)); + case DC_SIGCHAR_UINT: return Py_BuildValue("I", dcCallInt (gpCall, pfunc)); + case DC_SIGCHAR_LONG: return Py_BuildValue("l", dcCallLong (gpCall, pfunc)); + case DC_SIGCHAR_ULONG: return Py_BuildValue("k", dcCallLong (gpCall, pfunc)); + case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", dcCallLongLong(gpCall, pfunc)); + case DC_SIGCHAR_ULONGLONG: return Py_BuildValue("K", dcCallLongLong(gpCall, pfunc)); + case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat (gpCall, pfunc)); + case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble (gpCall, pfunc)); + case DC_SIGCHAR_STRING: return Py_BuildValue("s", dcCallPointer (gpCall, pfunc)); + case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer (gpCall, pfunc)); // @@@ probably not working, there is no "p" + default: return PyErr_Format(PyExc_RuntimeError, "invalid return type signature"); } } @@ -275,4 +288,3 @@ gpCall = dcNewCallVM(4096); } -