Mercurial > pub > dyncall > bindings
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 |