comparison python/pydc/pydcext.c @ 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 bf5625bb6f05
children edbbd467f50a
comparison
equal deleted inserted replaced
15:1673ab696715 16:a40084782546
13 #include "dynload.h" 13 #include "dynload.h"
14 #include <limits.h> 14 #include <limits.h>
15 15
16 /* PyCObject destructor callback for libhandle */ 16 /* PyCObject destructor callback for libhandle */
17 17
18 void free_library(void* libhandle) 18 void free_library(void* libhandle)
19 { 19 {
20 if (libhandle != 0) 20 if (libhandle != 0)
21 dlFreeLibrary(libhandle); 21 dlFreeLibrary(libhandle);
22 } 22 }
23 23
47 const char* symbol; 47 const char* symbol;
48 void* libhandle; 48 void* libhandle;
49 void* funcptr; 49 void* funcptr;
50 50
51 if ( !PyArg_ParseTuple(args,"Os", &pcobj, &symbol) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); 51 if ( !PyArg_ParseTuple(args,"Os", &pcobj, &symbol) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch");
52 52
53 libhandle = PyCObject_AsVoidPtr(pcobj); 53 libhandle = PyCObject_AsVoidPtr(pcobj);
54 54
55 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is null"); 55 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is null");
56 56
57 funcptr = dlFindSymbol(libhandle, symbol); 57 funcptr = dlFindSymbol(libhandle, symbol);
58 if (!funcptr) 58 if (!funcptr)
59 return PyErr_Format(PyExc_RuntimeError, "symbol '%s' not found", symbol); 59 return PyErr_Format(PyExc_RuntimeError, "symbol '%s' not found", symbol);
60 60
61 return PyCObject_FromVoidPtr(funcptr, NULL); 61 return PyCObject_FromVoidPtr(funcptr, NULL);
62 } 62 }
63 63
68 { 68 {
69 PyObject* pcobj; 69 PyObject* pcobj;
70 void* libhandle; 70 void* libhandle;
71 71
72 if ( !PyArg_ParseTuple(args,"o", &pcobj) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); 72 if ( !PyArg_ParseTuple(args,"o", &pcobj) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch");
73 73
74 libhandle = PyCObject_AsVoidPtr(pcobj); 74 libhandle = PyCObject_AsVoidPtr(pcobj);
75 75
76 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is NULL"); 76 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is NULL");
77 77
78 dlFreeLibrary(libhandle); 78 dlFreeLibrary(libhandle);
79 PyCObject_SetVoidPtr(pcobj,0); 79 PyCObject_SetVoidPtr(pcobj,0);
80 Py_RETURN_NONE; 80 Py_RETURN_NONE;
96 int l; 96 int l;
97 const char* ptr; 97 const char* ptr;
98 char ch; 98 char ch;
99 int pos; 99 int pos;
100 void* pfunc; 100 void* pfunc;
101 101
102 if ( !PyArg_ParseTuple(in_args,"OsO", &pcobj_funcptr, &signature, &args) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); 102 if ( !PyArg_ParseTuple(in_args,"OsO", &pcobj_funcptr, &signature, &args) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch");
103 pfunc = PyCObject_AsVoidPtr(pcobj_funcptr); 103 pfunc = PyCObject_AsVoidPtr(pcobj_funcptr);
104 if ( !pfunc ) return PyErr_Format( PyExc_RuntimeError, "function pointer is NULL" ); 104 if ( !pfunc ) return PyErr_Format( PyExc_RuntimeError, "function pointer is NULL" );
105 l = PyTuple_Size(args); 105 l = PyTuple_Size(args);
106 106
107 ptr = signature; 107 ptr = signature;
108 pos = 0; 108 pos = 0;
109 109
110 dcReset(gpCall); 110 dcReset(gpCall);
111 111
112 while ( (ch = *ptr) != '\0' && ch != ')' ) 112 while ( (ch = *ptr) != '\0' && ch != ')' )
113 { 113 {
114 PyObject* po; 114 PyObject* po;
115 115
116 int index = pos+1; 116 int index = pos+1;
117 117
118 if (pos > l) return PyErr_Format( PyExc_RuntimeError, "expecting more arguments" ); 118 if (pos > l) return PyErr_Format( PyExc_RuntimeError, "expecting more arguments" );
119 119
120 po = PyTuple_GetItem(args,pos); 120 po = PyTuple_GetItem(args,pos);
121 121
122 switch(ch) 122 switch(ch)
123 { 123 {
124 case DC_SIGCHAR_BOOL: 124 case DC_SIGCHAR_BOOL:
125 { 125 {
126 DCbool b; 126 DCbool b;
127 if ( !PyBool_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a bool", index ); 127 if ( !PyBool_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a bool", index );
128 b = (Py_True == po) ? DC_TRUE : DC_FALSE; 128 b = (Py_True == po) ? DC_TRUE : DC_FALSE;
129 dcArgBool(gpCall, b); 129 dcArgBool(gpCall, b);
130 } 130 }
131 break; 131 break;
132 case DC_SIGCHAR_CHAR: 132 case DC_SIGCHAR_CHAR:
133 case DC_SIGCHAR_UCHAR:
133 { 134 {
134 DCchar c; 135 DCchar c;
135 if ( PyString_Check(po) ) 136 if ( PyString_Check(po) )
136 { 137 {
137 // Py_ssize_t l; 138 // Py_ssize_t l;
138 size_t l; 139 size_t l;
139 char* s; 140 char* s;
140 l = PyString_GET_SIZE(po); 141 l = PyString_GET_SIZE(po);
141 if (l != 1) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string with length of 1 (a char string)", index ); 142 if (l != 1) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string with length of 1 (a char string)", index );
142 s = PyString_AsString(po); 143 s = PyString_AsString(po);
143 c = (DCchar) s[0]; 144 c = (DCchar) s[0];
144 } 145 }
145 else if ( PyInt_Check(po) ) 146 else if ( PyInt_Check(po) )
146 { 147 {
147 long l; 148 long l;
148 l = PyInt_AsLong(po); 149 l = PyInt_AsLong(po);
149 if ( (l > CHAR_MAX) || (l < CHAR_MIN)) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a char code", index ); 150 if ( (l > CHAR_MAX) || (l < CHAR_MIN)) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a char code", index );
150 c = (DCchar) l; 151 c = (DCchar) l;
151 } 152 }
152 else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index ); 153 else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index );
153 dcArgChar(gpCall, c); 154 dcArgChar(gpCall, c);
154 } 155 }
155 break; 156 break;
156 case DC_SIGCHAR_SHORT: 157 case DC_SIGCHAR_SHORT:
158 case DC_SIGCHAR_USHORT:
157 { 159 {
158 DCshort s; 160 DCshort s;
159 long v; 161 long v;
160 if ( !PyInt_Check(po) ) 162 if ( !PyInt_Check(po) )
161 return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index ); 163 return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index );
162 v = PyInt_AS_LONG(po); 164 v = PyInt_AS_LONG(po);
163 if ( (v < SHRT_MIN) || (v > SHRT_MAX) ) 165 if ( (v < SHRT_MIN) || (v > SHRT_MAX) )
164 return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a short value", index ); 166 return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a short value", index );
165 s = (DCshort) v; 167 s = (DCshort) v;
166 dcArgShort(gpCall, s); 168 dcArgShort(gpCall, s);
167 } 169 }
168 break; 170 break;
169 case DC_SIGCHAR_INT: 171 case DC_SIGCHAR_INT:
172 case DC_SIGCHAR_UINT:
170 { 173 {
171 long v; 174 long v;
172 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); 175 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index );
173 v = PyInt_AS_LONG(po); 176 v = PyInt_AS_LONG(po);
174 dcArgInt(gpCall, (DCint) v ); 177 dcArgInt(gpCall, (DCint) v );
175 } 178 }
176 break; 179 break;
177 case DC_SIGCHAR_LONG: 180 case DC_SIGCHAR_LONG:
181 case DC_SIGCHAR_ULONG:
178 { 182 {
179 long v; 183 long v;
180 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); 184 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index );
181 v = PyInt_AsLong(po); 185 v = PyInt_AsLong(po);
182 186
183 } 187 }
184 break; 188 break;
185 case DC_SIGCHAR_LONGLONG: 189 case DC_SIGCHAR_LONGLONG:
190 case DC_SIGCHAR_ULONGLONG:
186 { 191 {
187 PY_LONG_LONG pl; 192 PY_LONG_LONG pl;
188 DClonglong dl; 193 DClonglong dl;
189 if ( !PyLong_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a long long", index ); 194 if ( !PyLong_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a long long", index );
190 pl = PyLong_AsLongLong(po); 195 pl = PyLong_AsLongLong(po);
203 case DC_SIGCHAR_DOUBLE: 208 case DC_SIGCHAR_DOUBLE:
204 { 209 {
205 double d; 210 double d;
206 if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); 211 if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index );
207 d = PyFloat_AsDouble(po); 212 d = PyFloat_AsDouble(po);
208 dcArgDouble(gpCall, d); 213 dcArgDouble(gpCall, d);
209 } 214 }
210 break; 215 break;
211 case DC_SIGCHAR_POINTER: 216 case DC_SIGCHAR_POINTER:
212 { 217 {
213 DCpointer ptr; 218 DCpointer ptr;
240 245
241 if (ch == '\0') return PyErr_Format( PyExc_RuntimeError, "return value missing in signature"); 246 if (ch == '\0') return PyErr_Format( PyExc_RuntimeError, "return value missing in signature");
242 247
243 ch = *++ptr; 248 ch = *++ptr;
244 249
245 switch(ch) 250 switch(ch)
246 { 251 {
247 case DC_SIGCHAR_VOID: dcCallVoid (gpCall, pfunc); Py_RETURN_NONE; 252 case DC_SIGCHAR_VOID: dcCallVoid (gpCall, pfunc); Py_RETURN_NONE;
248 case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool (gpCall, pfunc)); 253 case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool (gpCall, pfunc));
249 case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt (gpCall, pfunc)); 254 case DC_SIGCHAR_CHAR: return Py_BuildValue("b", dcCallChar (gpCall, pfunc));
250 case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", (unsigned long long)dcCallLongLong(gpCall, pfunc)); 255 case DC_SIGCHAR_UCHAR: return Py_BuildValue("B", dcCallChar (gpCall, pfunc));
251 case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat (gpCall, pfunc)); 256 case DC_SIGCHAR_SHORT: return Py_BuildValue("h", dcCallShort (gpCall, pfunc));
252 case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble (gpCall, pfunc)); 257 case DC_SIGCHAR_USHORT: return Py_BuildValue("H", dcCallShort (gpCall, pfunc));
253 case DC_SIGCHAR_STRING: return Py_BuildValue("s", dcCallPointer (gpCall, pfunc)); 258 case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt (gpCall, pfunc));
254 case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer (gpCall, pfunc)); 259 case DC_SIGCHAR_UINT: return Py_BuildValue("I", dcCallInt (gpCall, pfunc));
255 default: return PyErr_Format( PyExc_RuntimeError, "invalid return type signature"); 260 case DC_SIGCHAR_LONG: return Py_BuildValue("l", dcCallLong (gpCall, pfunc));
261 case DC_SIGCHAR_ULONG: return Py_BuildValue("k", dcCallLong (gpCall, pfunc));
262 case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", dcCallLongLong(gpCall, pfunc));
263 case DC_SIGCHAR_ULONGLONG: return Py_BuildValue("K", dcCallLongLong(gpCall, pfunc));
264 case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat (gpCall, pfunc));
265 case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble (gpCall, pfunc));
266 case DC_SIGCHAR_STRING: return Py_BuildValue("s", dcCallPointer (gpCall, pfunc));
267 case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer (gpCall, pfunc)); // @@@ probably not working, there is no "p"
268 default: return PyErr_Format(PyExc_RuntimeError, "invalid return type signature");
256 } 269 }
257 } 270 }
258 271
259 272
260 static PyMethodDef pydcMethods[] = { 273 static PyMethodDef pydcMethods[] = {
273 if (m == NULL) 286 if (m == NULL)
274 return; 287 return;
275 gpCall = dcNewCallVM(4096); 288 gpCall = dcNewCallVM(4096);
276 } 289 }
277 290
278