# Allowing python to call the output of cfunction

**URL:** <https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 9, 2017, 10:19pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376 "2017-01-09T22:19:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![JoshLangsfeld](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshlangsfeld/32/8211_2.png) [@JoshLangsfeld](https://discourse.julialang.org/u/JoshLangsfeld)\
**Post date:** [January 9, 2017, 10:19pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/1 "2017-01-09T22:19:01Z")

</div>

This is really a PyCall question instead of a pure Julia question but maybe others will find it useful. Basically, I’m interested in the following steps:

- Define a one-argument Julia function.
- Obtain a `Ptr{Void}` to it using `cfunction`.
- Store the function pointer in a python class (using PyCall).
- Sometime later, call it from the python class with an argument (`Ptr{Void}` again) sent from Julia.

Is this doable and/or coherent? Keywords and links to resources that could help me better understand this type of problem would be welcome too.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 10, 2017, 1:55am UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/2 "2017-01-10T01:55:16Z")

</div>

PyCall already does this. If you have a Julia function `f(x)`, just pass it to a Python function (or, more explicitly, call `PyObject(f)`) to convert it to a callable Python object. Internally, the Python object is a C struct with a `tp_call` member that is a pointer to a `cfunction` pointer, which calls back to the Julia function `f` (which is compiled like any other Julia function).

---

<div class="post-metadata">

**Author:** ![JoshLangsfeld](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshlangsfeld/32/8211_2.png) [@JoshLangsfeld](https://discourse.julialang.org/u/JoshLangsfeld)\
**Post date:** [January 10, 2017, 7:26pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/3 "2017-01-10T19:26:08Z")

</div>

Thanks for the quick reply. The issue for me with the current PyCall setup is that the callback is wrapped in a different Julia function. I’m trying to do a inter-thread notification system using `uv_async_send` and so I can’t run Julia functions from the python-invoked callback.

Would it be feasible to transfer the callback wrapping you did in Julia to the python side? Any pointers/references for going that direction?

---

<div class="post-metadata">

**Author:** ![JoshLangsfeld](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshlangsfeld/32/8211_2.png) [@JoshLangsfeld](https://discourse.julialang.org/u/JoshLangsfeld)\
**Post date:** [January 10, 2017, 8:07pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/4 "2017-01-10T20:07:42Z")

</div>

Here’s a trivial example of this setup. Save both files in the same directory and just run `julia PyCB.jl`. Note that this doesn’t work on julia master, I assume because of [PyCall#343](https://github.com/JuliaPy/PyCall.jl/issues/343).

I assume this could work if I could somehow run `cfunction` on `cb` and pass it to be called directly by python.

PyCB.jl:

```julia
module PyCB

using PyCall

function cb(handle)
    ccall(:uv_async_send, Cint, (Ptr{Void},), handle)
end

function go()
    pycb_obj = pyimport("pycb")["CB"](cb)

    c = Base.AsyncCondition()
    @async begin
        wait(c)
        println("Notified!")
    end

    pycb_obj[:call](c.handle)
    sleep(1)
end

function __init__ ()
    pypath = PyVector(pyimport("sys")["path"])
    if ! (dirname(@ __FILE__ ) in pypath)
        unshift!(pypath, dirname(@ __FILE__ ))
    end
end

end

if ! isinteractive()
    PyCB.go()
end

```

pycb.py:

```julia
import threading
import time

class CB(object):
    def __init__ (self, cb):
        self._cb = cb

    def call(self, arg):
        print("Starting thread...")
        t = threading.Thread(target=self._cb, args=(arg,))
        t.start()
        time.sleep(1)
        print("Exiting callback")

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 10, 2017, 10:58pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/5 "2017-01-10T22:58:30Z")

</div>

Doesn’t the python ctypes module have code to invoke a C function pointer? This should work fine with a cfunction.

---

<div class="post-metadata">

**Author:** ![JoshLangsfeld](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshlangsfeld/32/8211_2.png) [@JoshLangsfeld](https://discourse.julialang.org/u/JoshLangsfeld)\
**Post date:** [January 12, 2017, 8:03pm UTC](https://discourse.julialang.org/t/allowing-python-to-call-the-output-of-cfunction/1376/6 "2017-01-12T20:03:20Z")

</div>

Thanks, that pointer was what I needed. After a bit of googling I’ve got it working nicely.
