Commit | Line | Data |
---|---|---|
34e49164 C |
1 | <html> |
2 | <head> | |
3 | <title>Module Pycaml</title> | |
4 | </head> | |
5 | <body> | |
6 | <table border=0 width="100%"><tr><td bgcolor="#c0c0c0"> | |
7 | <h1>Pycaml</h1> | |
8 | </td></tr></table> | |
9 | <p> | |
10 | <h2>What is Pycaml</h2> | |
11 | A library written by <a href=mailto:arty@users.sourceforge.net> | |
12 | arty@users.sourceforge.net</a> which follows the Python/C API as | |
13 | closely as possible, while | |
14 | providing equivalent functionality for objective caml. This is built | |
15 | against python 2.x and Ocaml 3.04.<p> It is intended to allow users to | |
16 | build native ocaml libraries and use them from python, and alternately, | |
17 | in order to allow ocaml users to benefit from linkable libraries provided | |
18 | for python.<p> | |
19 | I created this library in order to take advantage of python binding for | |
20 | certain native libraries from ocaml. While it is true that I could have | |
21 | written new interfaces specifically for ocaml, the python interface is | |
22 | sufficient for my needs, and this project was easier.<p> | |
23 | ||
24 | <b>Note:</b> Unfortunately, the symbol <tt>init_exceptions</tt> exists in | |
25 | both compiled ocaml code, and the python runtime. In order to proceed, you | |
26 | must rename this symbol either in the ocaml distribution (in byterun/fail.c, | |
27 | and byterun/startup.c), or in the python distribution, and rebuild the | |
28 | software appropriately.<p> | |
29 | ||
30 | Please edit the <tt>Makefile</tt> to put in your system's libraries used for | |
31 | compiling programs embedded with python. This library compiles on most | |
32 | linux boxes without modification. The python interpreter is used to determine | |
33 | the path to the python library and must be in your path when you run make. | |
34 | <p> | |
35 | ||
36 | <b>Get the distribution here:</b><a href=pycaml.tar.gz>pycaml.tar.gz</a><p> | |
37 | ||
38 | Because these are made to closely mirror the python API, the user should | |
39 | become familiar with the python API.<p> | |
40 | Given Ocaml parameter passing convention, it was convenient to pass multiple | |
41 | arguments as members of a tuple, but single arguments without. Consequently, | |
42 | functions with arity 1, such as pytuple_new are called as<p> | |
43 | <pre> | |
44 | pytuple_new 3 ;; | |
45 | </pre><p> | |
46 | And functions with more arguments are called as<p> | |
47 | <pre> | |
48 | pydict_getitemstring (dict,"keystring") ;; | |
49 | </pre> | |
50 | ||
51 | <h2>Module Pycaml</h2> | |
52 | ||
53 | <h3>Visible Types</h3> | |
54 | ||
55 | <table border=0> | |
56 | <tr bgcolor="#c0c0c0"><td>type</td><td width="100%">pyobject</td></tr> | |
57 | <tr><td colspan=2> | |
58 | The abstract type of python objects. | |
59 | </td></tr> | |
60 | <tr bgcolor="#c0c0c0"><td>type</td><td>pyobject_type =</td></tr> | |
61 | <tr><td align=right></td><td>TupleType</td></tr> | |
62 | <tr><td align=right>|</td><td>StringType</td></tr> | |
63 | <tr><td align=right>|</td><td>IntType</td></tr> | |
64 | <tr><td align=right>|</td><td>FloatType</td></tr> | |
65 | <tr><td align=right>|</td><td>ListType</td></tr> | |
66 | <tr><td align=right>|</td><td>NoneType</td></tr> | |
67 | <tr><td align=right>|</td><td>CallableType</td></tr> | |
68 | <tr><td align=right>|</td><td>ModuleType</td></tr> | |
69 | <tr><td align=right>|</td><td>ClassType</td></tr> | |
70 | <tr><td align=right>|</td><td>TypeType</td></tr> | |
71 | <tr><td align=right>|</td><td>OtherType</td></tr> | |
72 | <tr><td colspan=2> | |
73 | The type representing the range of types available to python programs. | |
74 | Values of this type are provided by the pytype function, and identify the | |
75 | python type of opaque pyobject objects. | |
76 | </td></tr></table> | |
77 | ||
78 | <h3>Supported Functions from the Python/C API</h3> | |
79 | In each case, the signature of the function is unchanged from the Python/C | |
80 | API except for the case of 'out' pointer to pointer parameters; | |
81 | in the case of a single return, the returned value is copied, otherwise, | |
82 | a tuple is created with copies of all output parameters. In the case of | |
83 | zero parameter, or void return, unit is used.<p> | |
84 | In python API functions that take a FILE *, an int file descriptor is used | |
85 | instead such as those returned by the Unix library.<p> | |
86 | ||
87 | <h4>fun unit -> unit</h4> | |
88 | py_initialize, py_finalize, pyerr_print, pyerr_clear, pyimport_cleanup | |
89 | <h4>fun int -> unit</h4> | |
90 | py_exit, pyerr_printex | |
91 | <h4>fun string -> unit</h4> | |
92 | py_setprogramname, py_setpythonhome | |
93 | <h4>fun unit -> int</h4> | |
94 | py_isinitialized, pyeval_getrestricted | |
95 | <h4>fun string -> int</h4> | |
96 | pyrun_simplestring, pyimport_importfrozenmodule, | |
97 | <h4>fun (int * string) -> int</h4> | |
98 | pyrun_anyfile, pyrun_simplefile, pyrun_interactiveone, pyrun_interactiveloop, | |
99 | py_fdisinteractive | |
100 | <h4>fun (int * string * int) -> int</h4> | |
101 | pyrun_anyfileex, pyrun_simplefileex | |
102 | <h4>fun unit -> string</h4> | |
103 | py_getprogramname, py_getpthonhome, py_getprogramfullpath, py_getprefix, | |
104 | py_getexecprefix, py_getpath, py_getversion, py_getplatform, py_getcopyright, | |
105 | py_getcompiler, py_getbuildinfo | |
106 | <h4>fun (string * int * pyobject * pyobject) -> pyobject</h4> | |
107 | pyrun_string | |
108 | <h4>fun (int * string * int * pyobject * pyobject) -> pyobject</h4> | |
109 | pyrun_file | |
110 | <h4>fun (int * string * int * pyobject * pyobject * int) -> pyobject</h4> | |
111 | pyrun_fileex | |
112 | <h4>fun (string * string * int) -> pyobject</h4> | |
113 | py_compilestring | |
114 | <h4>fun (pyobject * int * int) -> int</h4> | |
115 | pyobject_print, pytuple_getslice, pysequence_getslice</h4> | |
116 | <h4>fun pyobject -> pyobject</h4> | |
117 | pyobject_repr, pyobject_str, pyobject_unicode, pydict_keys, pydict_values, | |
118 | pydict_items, pydict_copy, pymodule_getdict, pymethod_function, pymethod_self, | |
119 | pymethod_class, pymodule_getdict, pyimport_reloadmodule, pyobject_type, | |
120 | pynumber_negative, pynumber_positive, pynumber_absolute, pynumber_invert, | |
121 | pynumber_int, pynumber_long, pynumber_float, pysequence_tuple, pysequence_list | |
122 | <h4>fun (pyobject * pyobject * int) -> pyobject</h4> | |
123 | pyobject_richcompare | |
124 | <h4>fun (pyobject * string) -> pyobject</h4> | |
125 | pyobject_getattrstring, pydict_getitemstring, pysequence_fast, | |
126 | pymapping_haskeystring, pymapping_getitemstring | |
127 | <h4>fun (pyobject * pyobject) -> pyobject</h4> | |
128 | pyobject_getattr, pystring_format, pydict_getitem, pyinstance_newraw, | |
129 | pyeval_callobject, pyobject_getitem, pyobject_delitem, pynumber_add, | |
130 | pynumber_subtract, pynumber_multiply, pynumber_divide, pynumber_remainder, | |
131 | pynumber_divmod, pynumber_lshift, pynumber_rshift, pynumber_and, pynumber_xor, | |
132 | pynumber_or, pynumber_inplaceadd, pynumber_inplacesubtract, pynumber_inplacemultiply, pynumber_inplacedivide, pynumber_inplaceremainder, pynumber_inplacelshift, pynumber_inplacershift, pynumber_inplaceand, pynumber_inplacexor, pynumber_inplaceor, pysequence_concat, pysequence_inplaceconcat | |
133 | <h4>fun pyobject -> int</h4> | |
134 | pyobject_istrue, pyobject_not, pycalable_check, pystring_size, pydict_size, | |
135 | pytuple_new, pyerr_exceptionmatches, pyobject_size, pynumber_check, | |
136 | pysequence_check, pysequence_size, pysequence_length, pymapping_check, | |
137 | pymapping_size, pymapping_length, pyint_asint | |
138 | <h4>fun (pyobject * pyobject) -> int</h4> | |
139 | pyobject_compare, pyobject_hasattr, pydict_delitem, | |
140 | pyerr_givenexceptionmatches, pysequence_count, pysequence_contains, | |
141 | pysequence_in, pysequence_index, pymapping_haskey | |
142 | <h4>fun (pyobject * pyobject * int) -> int</h4> | |
143 | pyobject_richcomparebool, pysequence_delitem | |
144 | <h4>fun (pyobject * string * pyobject) -> int</h4> | |
145 | pyobject_setattrstring, pydict_setitemstring | |
146 | <h4>fun (pyobject * string) -> int</h4> | |
147 | pyobject_hasattrstring, pydict_delitemstring, pysequence_inplacerepeat | |
148 | <h4>fun (pyobject * pyobject) -> (pyobject * pyobject)</h4> | |
149 | pynumber_coerce, pynumber_coerceex | |
150 | <h4>fun (pyobject * pyobject * pyobject) -> int</h4> | |
151 | pyobject_setattr, pydict_setitem, pyobject_setitem | |
152 | <h4>fun pyobject -> int64</h4> | |
153 | pyobject_hash, pyint_aslong | |
154 | <h4>fun pyobject -> string</h4> | |
155 | pystring_asstring, pymodule_getname, pymodule_getfilename | |
156 | <h4>fun (pyobject * pyobject) -> pyobject</h4> | |
157 | pystring_concat, pystring_concatanddel | |
158 | <h4>fun string -> pyobject</h4> | |
159 | pystring_fromstring, pymodule_new, pyimport_addmodule, pyimport_importmodule, | |
160 | pyimport_import | |
161 | <h4>fun unit -> pyobject</h4> | |
162 | pydict_new, pyerr_occurred, pyimport_getmoduledict, pyeval_getbuiltins, | |
163 | pyeval_getglobals, pyeval_getlocals, pyeval_getframe | |
164 | <h4>fun pyobject -> unit</h4> | |
165 | pydict_clear, pyerr_setnone | |
166 | <h4>fun (pyobject * int) -> (pyobject * pyobject * int)</h4> | |
167 | pydict_next | |
168 | <h4>fun int64 -> pyobject</h4> | |
169 | pyint_fromlong | |
170 | <h4>fun unit -> int64</h4> | |
171 | pyint_getmax | |
172 | <h4>fun float -> pyobject</h4> | |
173 | pyfloat_fromdouble | |
174 | <h4>fun pyobject -> float</h4> | |
175 | pyfloat_asdouble | |
176 | <h4>fun int -> pyobject</h4> | |
177 | pytuple_new, pyint_fromint | |
178 | <h4>fun (pyobject * int) -> pyobject</h4> | |
179 | pytuple_getitem, pysequence_repeat, pysequence_getitem | |
180 | <h4>fun (pyobject * int * pyobject) -> int</h4> | |
181 | pytuple_setitem, pysequence_setitem, pymapping_setitem | |
182 | <h4>fun (pyobject * pyobject * pyobject) -> pyobject</h4> | |
183 | pyslice_new, pyclass_new, pyinstance_new, pymethod_new, | |
184 | pyeval_callobjectwithkeywords, pynumber_power, pynumber_inplacepower | |
185 | <h4>fun (pyobject * int) -> (int * int * int)</h4> | |
186 | pyslice_getindices | |
187 | <h4>fun (int * int * int * int) -> pyobject</h4> | |
188 | pyrange_new | |
189 | <h4>fun (pyobject * pyobject) -> unit</h4> | |
190 | pyerr_setobject | |
191 | <h4>fun (pyobject * string) -> unit</h4> | |
192 | pyerr_setstring | |
193 | <h4>fun (pyobject * pyobject * pyobject) -> (pyobject * pyobject * pyobject)</h4> | |
194 | pyerr_fetch, pyerr_normalizeexception | |
195 | <h4>fun (pyobject * pyobject * pyobject) -> unit</h4> | |
196 | pyerr_restore | |
197 | <h4>fun (pyobject * string) -> pyobject</h4> | |
198 | pyimport_execcodemodule | |
199 | <h4>fun (string * pyobject * string) -> pyobject</h4> | |
200 | pyimport_execcodemoduleex | |
201 | <h4>fun (string * pyobject * pyobject * pyobject) -> pyobject</h4> | |
202 | pyimport_importmoduleex | |
203 | <h4>fun pyobject -> string</h4> | |
204 | pyobject_ascharbuffer, pyobject_asreadbuffer, pyobject_aswritebuffer | |
205 | <h4>fun (pyobject * int * int * pyobject) -> int</h4> | |
206 | pysequence_setslice | |
207 | <h4>fun (pyobject * int * int) -> int</h4> | |
208 | pysequence_delslice | |
209 | ||
210 | <h3>Unique Functions Needed for Ocaml</h3> | |
211 | In addition to the functions in the usual library, several new functions are | |
212 | provided which give specific support for ocaml.<p> | |
213 | ||
214 | <table border=0 width=100%> | |
215 | <tr bgcolor="#c0c0c0"> | |
216 | <td><b>pytuple_toarray</b></td> | |
217 | <td>pyobject -> pyobject array</td></tr> | |
218 | <tr><td colspan=2> | |
219 | Convert a python tuple to an ocaml array containing the same items. | |
220 | </td></tr> | |
221 | <tr bgcolor="#c0c0c0"> | |
222 | <td><b>pywrap_closure</b></td><td>(pyobject -> pyobject) -> pyobject</td></tr> | |
223 | <tr><td colspan=2> | |
224 | Create a python callable object from a closure. The closure receives the | |
225 | argument tuple from the invocation and returns a pyobject. | |
226 | </td></tr> | |
227 | <tr bgcolor="#c0c0c0"> | |
228 | <td><b>pywrap_value</b></td><td>'a -> pyobject</td></tr> | |
229 | <tr><td colspan=2> | |
230 | Create a simple void * style wrapping around an ocaml object. The object | |
231 | may be retrieved with <tt>pyunwrap_value : pyobject -> 'a</tt>. Use this | |
232 | to enclose an ocaml data structure in python to be used later. | |
233 | </td></tr> | |
234 | <tr bgcolor="#c0c0c0"> | |
235 | <td><b>pynull</b></td><td>unit -> pyobject</td></tr> | |
236 | <tr><td colspan=2> | |
237 | Generate the null PyObject * and return it. This may sound dangerous, but | |
238 | it is used by library calls to indicate errors to the python system. | |
239 | </td></tr> | |
240 | <tr bgcolor="#c0c0c0"> | |
241 | <td><b>pynone</b></td><td>unit -> pyobject</td></tr> | |
242 | <tr><td colspan=2> | |
243 | Generate a reference to the Py_None object. | |
244 | </td></tr> | |
245 | <tr bgcolor="#c0c0c0"> | |
246 | <td><b>pytuple_fromarray</b></td> | |
247 | <td>pyobject array -> pyobject</td></tr> | |
248 | <tr><td colspan=2> | |
249 | Create a pytuple (as would be used for a function call) from the given | |
250 | array. This may be used to implement varargs calls on python functions, | |
251 | and for other purposes. | |
252 | </td></tr> | |
253 | <tr bgcolor="#c0c0c0"> | |
254 | <td><b>pytuple_empty</b></td> | |
255 | <td>pyobject array -> pyobject</td></tr> | |
256 | <tr><td colspan=2> | |
257 | Shortcut for <tt>pytuple_new 0</tt> | |
258 | </td></tr> | |
259 | ||
260 | <tr bgcolor="#c0c0c0"> | |
261 | <td><b>pytuple_fromsingle</b></td> | |
262 | <td>pyobject -> pyobject</tt></td></tr> | |
263 | <tr><td colspan=2> | |
264 | Create a tuple with the single given object inside. Use this to create | |
265 | single element tuples as for a function call with one argument. | |
266 | </td></tr> | |
267 | ||
268 | <tr bgcolor="#c0c0c0"> | |
269 | <td><b>pytuple<i>1-5</i></b></td> | |
270 | <td>(pyobject * ...) -> pyobject</tt></td></tr> | |
271 | <tr><td colspan=2> | |
272 | Create a python tuple that has the same contents as the given ocaml tuple. | |
273 | </td></tr> | |
274 | ||
275 | <tr bgcolor="#c0c0c0"> | |
276 | <td><b>pytype</b></td> | |
277 | <td>pyobject -> pyobject_type</tt></td></tr> | |
278 | <tr><td colspan=2> | |
279 | Determine roughly which type family the given value belongs to. For example, | |
280 | <tt>pytype (pystring_fromstring "hi")</tt> yields <tt>StringType</tt>. | |
281 | </td></tr> | |
282 | </table> | |
283 | ||
284 | <h3>Sample Application</h3> | |
285 | This is the sample application that I developed the library with. It | |
286 | illustrates a python function call, as well as a call back into ocaml. | |
287 | The first form is used in cases where python libraries are to be used | |
288 | from ocaml, and the second would be used to produce native libraries in | |
289 | ocaml.<p> | |
290 | ||
291 | <pre> | |
292 | open Pycaml ;; | |
293 | ||
294 | let colorsys = pyimport_importmodule "colorsys" | |
295 | let dict = pymodule_getdict colorsys | |
296 | ||
297 | let triplet = pytuple3 (pyfloat_fromdouble 1.0, | |
298 | pyfloat_fromdouble 0.5, | |
299 | pyfloat_fromdouble 0.2) ;; | |
300 | ||
301 | let rgbtoyiq = pydict_getitemstring (dict,"rgb_to_yiq") | |
302 | let triplet = pyeval_callobject (rgbtoyiq,triplet) | |
303 | ||
304 | let _ = print_endline ((string_of_float | |
305 | (pyfloat_asdouble (pytuple_getitem (triplet,0)))) ^ | |
306 | " " ^ | |
307 | (string_of_float | |
308 | (pyfloat_asdouble (pytuple_getitem (triplet,1)))) ^ | |
309 | " " ^ | |
310 | (string_of_float | |
311 | (pyfloat_asdouble (pytuple_getitem (triplet,2))))) ;; | |
312 | ||
313 | let x = pywrap_closure | |
314 | (fun x -> print_string (pystring_asstring (pytuple_getitem (x,0))) ; | |
315 | pynone ()) | |
316 | ||
317 | let _ = pyeval_callobject | |
318 | (x,pytuple_fromsingle (pystring_fromstring "hi there")) | |
319 | </pre> | |
320 | </body> | |
321 | </html> |