Re: Weird bug? with CFUNCTYPE and glfw
Urs Schulz <[email protected]> Sun, 07 Jul 2013 12:02:33 +0200
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
Hi again,
UPDATE: Now that I had a theory, what may go wrong here I was able to
write a more minimal example without GLFW that reproduces this
behaviour. Again, Python 3.3.2:
#!/usr/bin/env python3
import ctypes as c
lib = c.CDLL("./libtest.so")
CALLBACK = c.CFUNCTYPE(None)
lib.reg(CALLBACK(lambda: print("lambda")))
lib.call()
def cb():
print("cb")
lib.call()
and the corresponding C code for libtest.so:
// compile with: gcc -shared -fPIC test.c -o libtest.so
typedef void(* cb)();
cb callback;
void reg(cb callb) {
callback = callb;
callback();
}
void call() {
callback();
}
The output of this is the following:
> lambda
> lambda
> cb
So I thought, this is not even a bug, but the CALLBACK object is simply
droped by Python because it can not know that libtest.so is still
storing a pointer to what ctypes has generated and also ctypes can not
know, that the libtest.so still has a pointer to the callback. When
changing the code to the following:
#!/usr/bin/env python3
import ctypes as c
lib = c.CDLL("./libtest.so")
CALLBACK = c.CFUNCTYPE(None)
callback = CALLBACK(lambda: print("lambda"))
lib.reg(callback)
lib.call()
def cb():
print("cb")
lib.call()
It works perfectly fine and telling me "lambda" 3 times. With the same
steps I was able to fix the GLFW code. Sorry for bothering you.
Cheers
Am Sonntag, den 07.07.2013, 11:35 +0200 schrieb Urs Schulz:
> Hi folks,
>
> I found a weird bug (or at least I don't understand whats happening)
> when writing some Python 3 code using GLFW 3.0.1. Unfortunately I was
> not able to reproduce the error with a selfwritten small C library, it
> only occours when using glfw on linux (testet on arch 64 bit).
>
> I reduced the problem to the following minimal code:
> #!/usr/bin/env python3
>
> import ctypes as c
>
> class GLFWwindow(c.Structure):
> pass
> GLFWwindow_p = c.POINTER(GLFWwindow)
> GLFWkeyfun = c.CFUNCTYPE(None, GLFWwindow_p, c.c_int, c.c_int, c.c_int,
> c.c_int)
>
> lib = c.CDLL("libglfw.so")
> lib.glfwCreateWindow.restype = GLFWwindow_p
>
> lib.glfwInit()
> win = lib.glfwCreateWindow(800, 600, "Title".encode(), None, None)
> lib.glfwSetKeyCallback(win, GLFWkeyfun(lambda w, key, scancode, action,
> mods: print(key, action)))
>
> #def cb(*args):
> # print(args)
>
> while True:
> lib.glfwPollEvents()
>
> The window is created successfully, but when I press a key I get the
> following errors in the console:
>
> Traceback (most recent call last):
> File "_ctypes/callbacks.c", line 260, in 'calling callback function'
> TypeError: 'LP_GLFWwindow' object is not callable
> Traceback (most recent call last):
> File "_ctypes/callbacks.c", line 260, in 'calling callback function'
> TypeError: 'LP_GLFWwindow' object is not callable
>
> (this block for each press and release). I don't know why it tries to
> call a LP_GLFWwindow object...
> But if I now uncomment the cb function (and not! changing any other
> thing inside the code) the output becomes even more weird:
>
> (<__main__.LP_GLFWwindow object at 0x7ff51e03edd0>, 87, 25, 1, 0)
> (<__main__.LP_GLFWwindow object at 0x7ff51e03edd0>, 87, 25, 0, 0)
>
> But I have never registered cb as a callback to glfwSetKeyCallback.
>
> So I tried changing to Python 2.7.5. The behaviour changes to this:
>
> Output without the cb-function:
>
> > 87 1
> > [1] 1795 segmentation fault (core dumped) ./test2.py
>
> and with cb-function:
>
> > (<__main__.LP_GLFWwindow object at 0x7f72fab86680>, 87, 25, 1, 0)
> > [1] 1758 segmentation fault (core dumped) ./test2.py
>
> The code header changed to:
>
> #!/usr/bin/env python2
> from __future__ import print_function
>
> the rest of the code is exactly the same.
>
> I have the following idea that may explain this:
> Python is freeing the lambda function, because GLFWkeyfun does not
> properly increment the reference counter on it. After this it creates
> the cb function, and stores it on the same memory where the lambda lived
> before, so this one gets called instead. But I don't know much about
> Python or ctypes internals so this is just speculation.
>
> I googled a lot but found nothing on this. I am using Python 3.3.2 and
> GLFW 3.0.1 both in the recent version from the arch repos (64 bit). You
> can find the glfw documentation at [1]. I'm not even sure if this is a
> bug or just missusage of the ctypes module or maybe even a bug inside
> gcc or glfw. If you need any other information (including hardware or
> system information) or require me to test stuff, please tell me.
>
> Cheers
>
> References:
> [1] http://www.glfw.org/docs/3.0/group__input.html
>
>
>
> ------------------------------------------------------------------------------
> This SF.net email is sponsored by Windows:
>
> Build for Windows Store.
>
> http://p.sf.net/sfu/windows-dev2dev
> _______________________________________________
> ctypes-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ctypes-users
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev