Commits

camlspotter committed 3292cac

wrap: OCaml value embedding in Python object

Comments (0)

Files changed (3)

     
     	Bug: Py_Main never returns to OCaml at exit(_), while CTRL+D works fine.
         **)
+
+      external unsafe_embed : 'a -> _Object t = "test_opycaml_create_wrap"
+
     end = struct
   
       external none : unit -> _None t = "opycaml_none"
     
       external _main : int -> string list -> int = "opycaml_Py_Main"
       let main argv = _main (List.length argv) argv
+
+      external unsafe_embed : 'a -> _Object t = "test_opycaml_create_wrap"
     end
 
     include X
     opycaml_compare,
     opycaml_hash,
     custom_serialize_default,
-    opycaml_deserialize
+    opycaml_deserialize // TODO
 };
 
 // struct custom_operations fnops = {
 }
 
 static PyMethodDef OPyCamlMethods[] = {
-    { "ocaml", opycaml_callback, METH_VARARGS, "Call registered OCaml functions" },
+    { "ocaml", opycaml_callback, METH_VARARGS, "Call registered OCaml functions" }, // static method
     { NULL, NULL, 0, NULL }
 };
 
 {
     initopycaml();
 }
+
+// Having OCaml value inside Python
+
+void opycaml_remove_wrap(value *statvp)
+{
+    remove_global_root(statvp); // now the reachables can be GCed
+    free(statvp);
+}
+
+PyCObject * opycaml_create_wrap(value v)
+{
+    // create a static for a copy of v
+    value *statvp = stat_alloc(sizeof(value));
+    *statvp = v;
+    // register *statvp as a global, to prevent GC of the reachables from statvp
+    register_global_root(statvp);
+    return PyCObject_FromVoidPtr(statvp, opycaml_remove_wrap); // create a new ref
+}
+
+value test_opycaml_create_wrap(value v)
+{
+    return Val_PyObject((PyObject *)opycaml_create_wrap(v), 0);
+}
       *)
     prerr_endline "Now you can use opycaml.ocaml(\"test\", 1, 2, 3) to call the test OCaml function from Python";
 
+
+    (* OCaml value => _Object t *)
+    let py_ocaml_1 = Base.unsafe_embed 1 in
+    Base.debug "py_ocaml_1" py_ocaml_1;
+    
     ignore (Base.main []);
     prerr_endline "exited from toploop";