Cython:将指针传递到函数中的指针,该函数采用void **

时间:2019-01-20 07:16:12

标签: c pointers cython

我正在尝试编写一个函数,该函数在某些条件下会将指向结构的指针更改为指向不同的结构。

我的约束是我想保留初始函数签名,该函数签名将指向指针(而不指向特定结构类型)的通用指针作为参数。

这行不通:

[nav] In [5]: %%cython -f 
         ...: ctypedef struct A: 
         ...:     int x 
         ...:     int y 
         ...:  
         ...: cdef fn(void **m): 
         ...:     # Arbitrary code that changes m[0] to point to another structure
         ...:     pass
         ...:      
         ...: cdef A a 
         ...: cdef A *ap = &a 
         ...: a.x = 2 
         ...: a.y = 3 
         ...: print(ap.x) 
         ...: fn(&ap) 
         ...: print(ap.x) 

Error compiling Cython file:
------------------------------------------------------------
...
cdef A a
cdef A *ap = &a
a.x = 2
a.y = 3
print(a.x)
fn(&ap)
  ^
------------------------------------------------------------

/home/me/.cache/ipython/cython/_cython_magic_3c3902694eafae18c66cb761d4a6b210.pyx:20:3: Cannot assign type 'A **' to 'void **'

我想这是因为即使我可以编写一个将void *作为参数并自动将任何传递的指针强制转换为void *的函数,也无法与指向a的指针一起使用无效指针,对吗?

如果是这样,如何传递结构指针指针,以便ap可以指向其他结构?

谢谢。

编辑:

进一步阅读后,我意识到这是C架构的“功能”。 This useful article给出了一些简要说明:

  

关于指针和内存分配的指针的一个侧面:尽管void *返回的malloc类型是一种“通用指针”,适合于分配给任何类型的指针或从任何类型的指针分配,假设类型void **不是“指向指针的通用指针”。我们的allocstr示例只能用于分配指向char的指针。无法使用通过void **指针间接返回通用指针的函数,因为当您尝试使用它时,例如通过声明和调用

double *dptr;
if(!hypotheticalwrapperfunc(100, sizeof(double), &dptr))
    fprintf(stderr, "out of memory\n");
  

您不会传递void **,而是传递double **

我收集到的信息是,我现在可以在函数签名中指定数据类型,还是返回新的赋值?

1 个答案:

答案 0 :(得分:0)

我通过传递函数的要求(即void **)解决了问题,然后在需要时进行强制转换:

[nav] In [5]: %%cython -f 
         ...: ctypedef struct A: 
         ...:     int x 
         ...:     int y 
         ...:  
         ...: cdef fn(void **m): 
         ...:     # Arbitrary code that changes m[0] to point to another structure
         ...:     pass
         ...:      
         ...: cdef A a 
         ...: cdef void *avp = <void *>&a
         ...: cdef A *ap = <A*>avp
         ...: a.x = 2 
         ...: a.y = 3 
         ...: print(ap.x) 
         ...: fn(&ap)
         ...: ap = <A*>avp # Must reassign
         ...: print(ap.x)