New submission from Dan <dtam...@astro.princeton.edu>:

I have a C struct 

typedef struct Effect {
    void* ptr;
} Effect;

where when I allocate the memory, the void* gets initialized to NULL, and pass 
back a pointer:

Effect* get_effect(){
    Effect* pEffect = malloc(sizeof(*pEffect));
    pEffect->ptr = NULL;
    return pEffect;
}

In Python, I need to call the C function to initialize, and then pass a 
REFERENCE to the pointer to another C function:

from ctypes import cdll, Structure, c_int, c_void_p, addressof, pointer, 
POINTER, c_double, byref
clibptr = cdll.LoadLibrary("libpointers.so")

class Effect(Structure):
    _fields_ = [("ptr", POINTER(c_double))]

clibptr.get_effect.restype = POINTER(Effect)
pEffect = clibptr.get_effect()
effect = pEffect.contents
clibptr.print_ptraddress(byref(effect.ptr))

But this prints an error, because effect.ptr is None, so byref(None) fails.
Below is full working code in the case where ptr is instead a double*, where 
there is no problem. 
As far as I can tell, there is no way to pass a c_void_p field by reference, 
which would be very useful!

#include <stdio.h>
#include <stdlib.h>

#define PRINT_MSG_2SX(ARG0, ARG1) printf("From C - [%s] (%d) - [%s]:  ARG0: 
[%s], ARG1: 0x%016llX\n", __FILE__, __LINE__, __FUNCTION__, ARG0, (unsigned 
long long)ARG1)

typedef struct Effect {
    double* ptr;
} Effect;

void print_ptraddress(double** ptraddress){
    PRINT_MSG_2SX("Address of Pointer:", ptraddress);
}

Effect* get_effect(){
    Effect* pEffect = malloc(sizeof(*pEffect));
    pEffect->ptr = NULL;
    print_ptraddress(&pEffect->ptr);
    return pEffect;
}

Python:

from ctypes import cdll, Structure, c_int, c_void_p, addressof, pointer, 
POINTER, c_double, byref
clibptr = cdll.LoadLibrary("libpointers.so")

class Effect(Structure):
    _fields_ = [("ptr", POINTER(c_double))]

clibptr.get_effect.restype = POINTER(Effect)
pEffect = clibptr.get_effect()

effect = pEffect.contents
clibptr.print_ptraddress(byref(effect.ptr))

gives matching addresses:

>From C - [pointers.c] (11) - [print_ptraddress]: ARG0: [Address of Pointer:], 
>ARG1: 0x00007FC2E1AD3770 From C - [pointers.c] (11) - [print_ptraddress]: 
>ARG0: [Address of Pointer:], ARG1: 0x00007FC2E1AD3770

----------
components: ctypes
messages: 330961
nosy: dtamayo
priority: normal
severity: normal
status: open
title: ctypes not possible to pass NULL c_void_p in structure by reference
type: behavior
versions: Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue35390>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to