Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 958729
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T00:54:47+00:00 2026-05-16T00:54:47+00:00

I am trying to wrap a C library using ctypes. One feature of the

  • 0

I am trying to wrap a C library using ctypes. One feature of the library is an ondestroy callback which is called when a handle returned by the library is about to be destroyed.

The callback has the signature:

void cb(f *beingdestroyed);

The API allows one to associate a user-specified void * with f when it is returned by the library. Hence I can associate the py_object being used to wrap it as user data. My plan is to have an is_valid field and when the callback is fired to extract the user_data and set this field to false.

My problem is how to go about extracting my high-level py_object; I can fetch the user data as a ctypes.void_p and cast to a ctypes.py_object but then I’ve only got the Python C API to work with. It is possible to back-cast to a high level object which I can work with by writing user_object.is_valid = 0?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T00:54:47+00:00Added an answer on May 16, 2026 at 12:54 am

    To elaborate on Thomas Heller’s answer:

    • The callback prototype should specify c_void_p for the context parameter
    • The argtypes for the library function should specify py_object for the context parameter
    • That function should be called with py_object(my_python_context_object)
    • Your Python implementation of the callback function should cast the context to a py_object, and extract its value: cast(context, py_object).value

    Here is a working example. Start with C source for a simple DLL:

    // FluffyBunny.c
    // Compile on windows with command line
    //      cl /Gd /LD FluffyBunny.c
    // Result is FluffyBunny.DLL, which exports one function:
    //      FluffyBunny() uses __cdecl calling convention.
    
    #include <windows.h>
    
    BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID) {
      return TRUE;
    }
    
    typedef int (*FLUFFYBUNNY_CALLBACK)(void *context);
    
    __declspec(dllexport) int FluffyBunny(FLUFFYBUNNY_CALLBACK cb, void *context) {
      int result = 0;
      int count = 0;
      if (cb) {
        while (result == 0) {
          result = (*cb)(context);
          ++count;
        }
      }
      return count;
    }
    

    And here is a Python program that invokes the DLL:

    # FluffyBunny.py
    from ctypes import *
    
    # Declare a class that will be used for context info in calls to FluffyBunny()
    class Rabbit:
        def __init__(self):
            self.count = 0
    
    # FluffyBunny() wants a callback function with the following C prototype:
    #     typedef int (*FLUFFYBUNNY_CALLBACK)(void *context);
    FLUFFYBUNNY_CALLBACK = CFUNCTYPE(c_int, c_void_p)
    
    # This DLL has been compiled with __cdecl calling convention.
    FluffyBunny_dll = CDLL('FluffyBunny.dll')
    
    # Get the function from the library. Its C prototype is:
    #     int FluffyBunny(FLUFFYBUNNY_CALLBACK cb, void *context);
    # Note that I use "py_object" instead of "c_void_p" for the context argument.
    FluffyBunny          = FluffyBunny_dll.FluffyBunny
    FluffyBunny.restype  = c_int
    FluffyBunny.argtypes = [FLUFFYBUNNY_CALLBACK, py_object]
    
    # Create Python version of the callback function.
    def _private_enumerateBunnies(context):
        # Convert the context argument to a py_object, and extract its value.
        # This gives us the original Rabbit object that was passed in to 
        # FluffyBunny().
        furball = cast(context, py_object).value
        # Do something with the context object.
        if furball:
            furball.count += 1
            print 'furball.count =', furball.count
            # Return non-zero as signal that FluffyBunny() should terminate
            return 0 if (furball.count < 10) else -1
        else:
            return -1
    
    # Convert it to a C-callable function.
    enumerateBunnies = FLUFFYBUNNY_CALLBACK(_private_enumerateBunnies)
    
    # Try with no context info.
    print 'no context info...'
    result = FluffyBunny(enumerateBunnies, None)
    print 'result=', result
    
    # Give it a Python object as context info.
    print 'instance of Rabbit as context info...'
    furball = Rabbit()
    result = FluffyBunny(enumerateBunnies, py_object(furball))
    print 'result=', result
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to wrap a class from a library I'm using in Lua. Specifially,
I am trying to wrap an external library in more idiomatic Clojure. This includes
I'm trying to wrap a dummy C libray using Cython. Here is the .h
I am trying to wrap a C++ library (for Sybase Ultralite) with Objective-C so
I'm trying to connect to MySQL database from node.js using db-mysql library. Everything works
I'm trying to wrap my head around this new concept called LINQ. Ever heard
I'm trying to wrap a c library in a high-level python interface with Boost.Python.
I'm trying to wrap my head around reflection, so I decided to add plugin
I've been trying to wrap my head around how threads work in Python, and
I'm trying to wrap my head around creating a toolbar (a tool band in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.