Mercurial > pub > dyncall > bindings
comparison python/pydc/pydcext.c @ 0:0cfcc391201f
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:26:28 +0100 |
parents | |
children | bf5625bb6f05 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0cfcc391201f |
---|---|
1 /****************************************************************************** | |
2 ** | |
3 ** pydc - python dyncall package | |
4 ** | |
5 ** python extension package in C | |
6 ** Copyright 2007 Daniel Adler. | |
7 ** | |
8 ** December 04, 2007 | |
9 ** | |
10 *****************************************************************************/ | |
11 | |
12 #include <Python.h> | |
13 #include "dynload.h" | |
14 #include <limits.h> | |
15 | |
16 /* PyCObject destructor callback for libhandle */ | |
17 | |
18 void free_library(void* libhandle) | |
19 { | |
20 if (libhandle != 0) | |
21 dlFreeLibrary(libhandle); | |
22 } | |
23 | |
24 /* load function */ | |
25 | |
26 static PyObject* | |
27 pydc_load(PyObject* self, PyObject* args) | |
28 { | |
29 const char* libpath; | |
30 void* libhandle; | |
31 | |
32 if ( !PyArg_ParseTuple(args,"s", &libpath) ) return PyErr_Format(PyExc_RuntimeError, "libpath argument (string) missing"); | |
33 | |
34 libhandle = dlLoadLibrary(libpath); | |
35 | |
36 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "dlLoadLibrary('%s') failed", libpath); | |
37 | |
38 return PyCObject_FromVoidPtr(libhandle, &free_library); | |
39 } | |
40 | |
41 /* find function */ | |
42 | |
43 static PyObject* | |
44 pydc_find(PyObject* self, PyObject* args) | |
45 { | |
46 PyObject* pcobj; | |
47 const char* symbol; | |
48 void* libhandle; | |
49 void* funcptr; | |
50 | |
51 if ( !PyArg_ParseTuple(args,"Os", &pcobj, &symbol) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); | |
52 | |
53 libhandle = PyCObject_AsVoidPtr(pcobj); | |
54 | |
55 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is null"); | |
56 | |
57 funcptr = dlFindSymbol(libhandle, symbol); | |
58 if (!funcptr) | |
59 return PyErr_Format(PyExc_RuntimeError, "symbol '%s' not found", symbol); | |
60 | |
61 return PyCObject_FromVoidPtr(funcptr, NULL); | |
62 } | |
63 | |
64 /* free function */ | |
65 | |
66 static PyObject* | |
67 pydc_free(PyObject* self, PyObject* args) | |
68 { | |
69 PyObject* pcobj; | |
70 void* libhandle; | |
71 | |
72 if ( !PyArg_ParseTuple(args,"o", &pcobj) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); | |
73 | |
74 libhandle = PyCObject_AsVoidPtr(pcobj); | |
75 | |
76 if (!libhandle) return PyErr_Format(PyExc_RuntimeError, "libhandle is NULL"); | |
77 | |
78 dlFreeLibrary(libhandle); | |
79 PyCObject_SetVoidPtr(pcobj,0); | |
80 Py_RETURN_NONE; | |
81 } | |
82 | |
83 #include "dyncall.h" | |
84 #include "dyncall_signature.h" | |
85 | |
86 DCCallVM* gpCall; | |
87 | |
88 /* call function */ | |
89 | |
90 static PyObject* | |
91 pydc_call(PyObject* self, PyObject* in_args) | |
92 { | |
93 PyObject* pcobj_funcptr; | |
94 const char* signature; | |
95 PyObject* args; | |
96 int l; | |
97 const char* ptr; | |
98 char ch; | |
99 int pos; | |
100 void* pfunc; | |
101 | |
102 if ( !PyArg_ParseTuple(in_args,"OsO", &pcobj_funcptr, &signature, &args) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); | |
103 pfunc = PyCObject_AsVoidPtr(pcobj_funcptr); | |
104 if ( !pfunc ) return PyErr_Format( PyExc_RuntimeError, "function pointer is NULL" ); | |
105 l = PyTuple_Size(args); | |
106 | |
107 ptr = signature; | |
108 pos = 0; | |
109 | |
110 dcReset(gpCall); | |
111 | |
112 while ( (ch = *ptr) != '\0' && ch != ')' ) | |
113 { | |
114 PyObject* po; | |
115 | |
116 int index = pos+1; | |
117 | |
118 if (pos > l) return PyErr_Format( PyExc_RuntimeError, "expecting more arguments" ); | |
119 | |
120 po = PyTuple_GetItem(args,pos); | |
121 | |
122 switch(ch) | |
123 { | |
124 case DC_SIGCHAR_BOOL: | |
125 { | |
126 DCbool b; | |
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; | |
129 dcArgBool(gpCall, b); | |
130 } | |
131 break; | |
132 case DC_SIGCHAR_CHAR: | |
133 { | |
134 DCchar c; | |
135 if ( PyString_Check(po) ) | |
136 { | |
137 // Py_ssize_t l; | |
138 size_t l; | |
139 char* s; | |
140 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 s = PyString_AsString(po); | |
143 c = (DCchar) s[0]; | |
144 } | |
145 else if ( PyInt_Check(po) ) | |
146 { | |
147 long l; | |
148 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 c = (DCchar) l; | |
151 } | |
152 else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index ); | |
153 dcArgChar(gpCall, c); | |
154 } | |
155 break; | |
156 case DC_SIGCHAR_SHORT: | |
157 { | |
158 DCshort s; | |
159 long v; | |
160 if ( !PyInt_Check(po) ) | |
161 return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index ); | |
162 v = PyInt_AS_LONG(po); | |
163 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 ); | |
165 s = (DCshort) v; | |
166 dcArgShort(gpCall, s); | |
167 } | |
168 break; | |
169 case DC_SIGCHAR_INT: | |
170 { | |
171 long v; | |
172 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); | |
173 v = PyInt_AS_LONG(po); | |
174 dcArgInt(gpCall, (DCint) v ); | |
175 } | |
176 break; | |
177 case DC_SIGCHAR_LONG: | |
178 { | |
179 long v; | |
180 if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); | |
181 v = PyInt_AsLong(po); | |
182 | |
183 } | |
184 break; | |
185 case DC_SIGCHAR_LONGLONG: | |
186 { | |
187 PY_LONG_LONG pl; | |
188 DClonglong dl; | |
189 if ( !PyLong_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a long long", index ); | |
190 pl = PyLong_AsLongLong(po); | |
191 dl = (DClonglong) pl; | |
192 dcArgLongLong(gpCall, dl ); | |
193 } | |
194 break; | |
195 case DC_SIGCHAR_FLOAT: | |
196 { | |
197 DCfloat f; | |
198 if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); | |
199 f = (float) PyFloat_AsDouble(po); | |
200 dcArgFloat(gpCall, f); | |
201 } | |
202 break; | |
203 case DC_SIGCHAR_DOUBLE: | |
204 { | |
205 double d; | |
206 if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); | |
207 d = PyFloat_AsDouble(po); | |
208 dcArgDouble(gpCall, d); | |
209 } | |
210 break; | |
211 case DC_SIGCHAR_POINTER: | |
212 { | |
213 DCpointer ptr; | |
214 if ( PyString_Check(po) ) { | |
215 ptr = (DCpointer) PyString_AsString(po); | |
216 } else if ( PyLong_Check(po) ) { | |
217 ptr = (DCpointer) ( (DCint) PyLong_AsLongLong(po) ); | |
218 } else { | |
219 return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a promoting pointer-type (int,string)", index ); | |
220 } | |
221 dcArgPointer(gpCall, ptr ); | |
222 } | |
223 break; | |
224 case 'S': | |
225 { | |
226 char* p; | |
227 if (!PyString_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string", index ); | |
228 p = PyString_AsString(po); | |
229 dcArgPointer(gpCall, (DCpointer) p ); | |
230 } | |
231 break; | |
232 default: return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch); | |
233 } | |
234 | |
235 ++pos; ++ptr; | |
236 | |
237 } | |
238 | |
239 if (pos != l) return PyErr_Format( PyExc_RuntimeError, "too many arguments"); | |
240 | |
241 if (ch == '\0') return PyErr_Format( PyExc_RuntimeError, "return value missing in signature"); | |
242 | |
243 ch = *++ptr; | |
244 | |
245 switch(ch) | |
246 { | |
247 case DC_SIGCHAR_VOID: dcCallVoid(gpCall, pfunc); Py_RETURN_NONE; | |
248 case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool(gpCall, pfunc) ); | |
249 case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt(gpCall, pfunc) ); | |
250 case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", (unsigned long long) dcCallLongLong(gpCall, pfunc) ); | |
251 case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat(gpCall, pfunc) ); | |
252 case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble(gpCall, pfunc) ); | |
253 case 's': return Py_BuildValue("s", dcCallPointer(gpCall, pfunc) ); | |
254 case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer(gpCall, pfunc) ); | |
255 default: return PyErr_Format( PyExc_RuntimeError, "invalid return type signature" ); | |
256 } | |
257 } | |
258 | |
259 | |
260 static PyMethodDef pydcMethods[] = { | |
261 {"load", pydc_load, METH_VARARGS, "load library"}, | |
262 {"find", pydc_find, METH_VARARGS, "find symbols"}, | |
263 {"free", pydc_free, METH_VARARGS, "free library"}, | |
264 {"call", pydc_call, METH_VARARGS, "call function"}, | |
265 {NULL,NULL,0,NULL} | |
266 }; | |
267 | |
268 PyMODINIT_FUNC | |
269 initpydcext(void) | |
270 { | |
271 PyObject* m; | |
272 m = Py_InitModule("pydcext", pydcMethods); | |
273 if (m == NULL) | |
274 return; | |
275 gpCall = dcNewCallVM(4096); | |
276 } | |
277 | |
278 |