Skip to content

Instantly share code, notes, and snippets.

@ihnorton
Last active December 13, 2015 22:09
Show Gist options
  • Save ihnorton/4982817 to your computer and use it in GitHub Desktop.
Save ihnorton/4982817 to your computer and use it in GitHub Desktop.
Julia callback upon Python object finalization
julia> require("test.jl")
Julia code
lfile PyPtr address: Ptr{Void} @0x000000000361d390
Julia code
weakref address: Ptr{Void} @0x0000000003622f70
Julia code: calling decref
C code: cb_wrapper
self: 0
arg: 3622f70
Julia code:
got callback from Python with arg address: Ptr{Void} @0x0000000003622f70
#include "Python.h"
// Compiles on ubuntu 12.04 with system python 2.7 using:
// gcc -I /usr/include/python2.7 -shared -fPIC -g -lpython2.7 test.c -o libtest
void(*jlcallback)(void*,void*);
void set_jl_callback(void* cb)
{
jlcallback = cb;
}
PyObject* cb_wrapper(PyObject* self, PyObject* arg)
{
printf("C code: cb_wrapper\n");
printf(" self: %lx\n", (unsigned long)self);
printf(" arg: %lx\n", (unsigned long)arg);
jlcallback(self,arg);
Py_RETURN_NONE;
}
PyMethodDef methods;
PyObject* pycb;
PyObject* gen_py_callback()
{
methods.ml_name = "callback";
methods.ml_meth = cb_wrapper;
methods.ml_flags = METH_O;
methods.ml_doc = NULL;
pycb = PyCFunction_New(&methods, NULL);
return pycb;
}
module F
using PyCall
pyinitialize()
lfile = PyObject( ccall( pyfunc(:PyFile_FromString), PyPtr, (Ptr{Uint8}, Ptr{Uint8}), bytestring("test.txt"), bytestring("w") ), None )
println("Julia code")
println(" lfile PyPtr address: ", lfile.o)
function jlcb(self::Ptr{Void}, arg::Ptr{Void})
println("Julia code:")
println(" got callback from Python with arg address: ", arg)
return convert(Int32, 0)
end
cb_jl = cfunction(jlcb, Int32, (Ptr{Void},Ptr{Void}))
cb_py = ccall( (:gen_py_callback, "./libtest"), Ptr{Void}, () )
ccall( (:set_jl_callback, "./libtest"), Void, (Ptr{Void},), cb_jl)
function do_test()
weakref = ccall( pyfunc(:PyWeakref_NewRef), PyPtr, (Ptr{Void}, Ptr{Void}), lfile, cb_py)
println("Julia code")
println(" weakref address: ", weakref)
println(" Julia code: calling decref")
pydecref(lfile)
end
end # Module
F.do_test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment