Python - 为什么无法更改C回调函数中的值?

时间:2015-04-23 04:11:46

标签: python ctypes

我尝试使用python ctype来调用C库(.so),这个C库有回调函数。 C源代码:

int showHelloword(int *result)
{
    *result = 1025;
    return 55;
}

void BSP_SHOW(int time,int (*callback)(int *result))
{
    int ret = 44;
    int boo = 4;
    while(time > 0){
        --time;
        if(time == 0){
            if(callback) {
                printf("boo %d\n",boo);      // I expect boo=4
                ret = callback(&boo);
                printf("Outfunc=%d\n",boo);  // I expect Outfunc=1025
                printf("ret=%d\n",ret);      // I expect ret=55
            }        
            callback = 0;
        }
        sleep(1);
    }
}

void main(){
    BSP_SHOW( 2, &showHelloword);
}

印刷品是:

boo=4
Outfunc=1025
ret=55

看起来没问题。

Makefile源:

gcc -c -fPIC -Wno-format-security -g main.c
gcc -shared -o libcall.so main.o
gcc main.o -o callback -ldl -lpthread -lrt 

然后,我尝试使用python ctype调用" BSP_SHOW"这个函数并获得回调函数。 Python来源:

Python版本:2.6.6

import sys
import os
import time
from ctypes import *
import struct
from Queue import *

class callback_api(object):

    def __init__(self):
        CDLL("/usr/lib64/librt.so",mode=RTLD_GLOBAL)
        path = "/root/workspace/callback/libcall.so"  `C library path`
        self.dll = cdll.LoadLibrary(path)

    def BSP_SHOW(self,sec, cb_func):
        self.dll.BSP_SHOW.restype = None
        self.dll.BSP_SHOW.argtypes = [c_int, qa_cb_prototype]
        self.dll.BSP_SHOW(c_int(sec),cb_func)


    def qa_callback(result):
        result = 1025 #it should change the value. but the result is not....
        return 88

qa_cb_prototype = CFUNCTYPE( c_int, POINTER(c_int))
qa_cache_cb_func = qa_cb_prototype(qa_callback)

if __name__ == '__main__':
    api = callback_api()
    api.BSP_SHOW(2,qa_cache_cb_func) `got it callback`

打印结果是。

cb=4
Outfunc=4 <---I expect it should be 1025,but not! 
ret=88 <---return value have been change by python callback.

有人知道这是python ctype限制还是我使用了错误的方法? 谢谢!

1 个答案:

答案 0 :(得分:0)

=运算符在python中重新分配变量。换句话说,您可以更改变量的含义。

您需要更改变量指向的内容。由于它是一个ctypes指针,你需要用0来索引它才能做到这一点。

    def qa_callback(result):
        result[0] = 1025
        return 88

请注意结果后的[0]

另请参阅:https://docs.python.org/2/library/ctypes.html#pointers