Search code examples
pythonc++callbackctypesloadlibrary

In python how do I set the value of a LP_c_ubyte


I am creating a Python wrapper for a C DLL using python ctypes. I am having trouble updating a pointer to value in memory with python.

In this example I have a DLL that has a register callback function. A invoke callback function that creates unsigned char variable, passes a pointer to that variable to the callback function, then prints the updated value of that variable.

What I expected to happen is that the python function callbackUpdateValue would update the value of foo, and the updated value would be printed in C DLL DoCallBack function. The value of 0 is printed instead of the expected value of 99

My question is: In python how do I update the value of foo in callbackUpdateValue so that it can be printed in the C DLL DoCallBack function?

I have minimized my code as much as possible

DLL C++ Code

The DLL has two functions. One to register up a callback, the other to invoke the callback and print the results.

#include <stdio.h>
typedef void(*FPCallback)(unsigned char * foo);
FPCallback g_Callback;

extern "C" __declspec( dllexport ) void RegisterCallback(void(*p_Callback)(unsigned char * foo)) {
    g_Callback = p_Callback ; 
}

extern "C" __declspec( dllexport ) void DoCallBack() {
    unsigned char foo = 0 ; 
    g_Callback( &foo ); 
    printf( "foo=%d\n", foo); 
}

Python code

The python code sets up the call back function, then calls the DoCallBack function from the DLL.

from ctypes import *

def callbackUpdateValue( foo ):
    foo = 99 

customDLL = cdll.LoadLibrary ("customeDLL.dll")

# RegisterCallback
CustomDLLCallbackFUNC = CFUNCTYPE(None, POINTER( c_ubyte))
CustomDLLCallback_func = CustomDLLCallbackFUNC( callbackUpdateValue )
RegisterCallback = customDLL.RegisterCallback
RegisterCallback.argtypes = [ CustomDLLCallbackFUNC ]
RegisterCallback( CustomDLLCallback_func ) 

# DoCallBack
DoCallBack = customDLL.DoCallBack

# Call the callback 
DoCallBack() 

Solution

  • The correct way to define the python callback is

    def callbackUpdateValue( foo ):
        foo[0] = 99
    

    where foo[0] dereferences the pointer. More info can be found here: https://docs.python.org/2.5/lib/ctypes-callback-functions.html