Cython:将 void* 转换为 double 和反向转换

标签 c pointers cython

要组合两个独立的 C 编写模块,我必须将函数指针存储在 double 组中(将其传递给模块),并稍后将其转换回来。 我试图坚持https://stackoverflow.com/a/35824907/4859499 但是,我无法在 Cython 中弄清楚:

cdef void* ptr = getTestPtr() # getting the function pointer
cdef TEST mytest = <TEST> ptr # testing the function pointer
mytest()                      # still works here

cdef double** dPptr = <double**> ptr
cdef double* dPtr = dPptr[0]
doubleArrayStorage[0] = dPtr[0] #storing in a given double array at index 0
################################################

# starting of back conversion:
cdef double* dPtr2 = &doubleArrayStorage[0]
cdef void** Pptr2 = <void**> dPtr2
cdef void* ptr2 =  Pptr2[0]
cdef TEST mytest2 = <TEST> ptr2
mytest2()                         #SEGMENTATION FAULT !

谢谢!

最佳答案

将函数指针转换为任何其他指针类型 is undefined behaviour in C所以不能保证有效(请参阅链接答案的最后一点)。实际上,指向 void* 的函数指针通常是可以的。不过,没有充分的理由将其存储为指向数字的指针。

查看您的代码:

cdef void* ptr = getTestPtr() # getting the function pointer
cdef TEST mytest = <TEST> ptr # testing the function pointer
mytest()                      # still works here

将函数指针转换为 void 指针,然后再转换回函数指针。可能没问题,但不能保证。

cdef double** dPptr = <double**> ptr

将函数指针转换为指向 double 型指针的指针。狡猾的。

cdef double* dPtr = dPptr[0]

您取消引用该指针。这可以让你知道函数存储在内存中的内容(即可执行代码)。您假装将该可执行代码解释为指向 double 型的指针。

doubleArrayStorage[0] = dPtr[0] #storing in a given double array at index 0

dPtr[0] 查找它通过将某些可执行代码误解为指向 double 的指针而选择的任意内存位。我很惊讶这里没有段错误。获取任意内存位的内容后,您将其存储在由 doubleArrayStorage 指向的地址中(您还没有告诉我们)。

################################################

# starting of back conversion:
cdef double* dPtr2 = &doubleArrayStorage[0]

&doubleArrayStorage[0] 读取然后获取 doubleArrayStorage 的地址。它相当于只编写doubleArrayStorage。您将其保存为双指针。这只是 doubleArrayStorage 的位置(即正确的双指针,但与原始函数无关)。

cdef void** Pptr2 = <void**> dPtr2

您将 doubleArrayStorage 的地址重新解释为指向 void 的指针。

cdef void* ptr2 =  Pptr2[0]

您取消引用该地址。 ptr2 包含 doubleArrayStorage 第一个元素中的内容,您假装它是 void*。实际上,它是您之前读取的任意内存位的内容。

cdef TEST mytest2 = <TEST> ptr2
mytest2()                         #SEGMENTATION FAULT !

您使用该任意内存位的内容作为函数指针并尝试执行它。

<小时/>

总之,我不相信有任何方法可以在 C 中安全地完成您想要做的事情(这意味着 Cython 也无法做到)。

关于Cython:将 void* 转换为 double 和反向转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41522760/

相关文章:

c - 将多维数组作为指向 C 中函数的指针传递会产生意想不到的结果

c - 为什么我们不能将字符串复制到字符指针,而我们可以直接将字符串分配给它?

c - C 中不同类型的外部变量的声明

python - Cython 程序比普通 Python 慢(10M 选项 3.5s vs 3.25s Black Scholes)——我错过了什么?

python - Cython 错误 : Coercion from Python not allowed without the GIL

c - 同时输入两个变量时如何显示逗号?

c++ - 如何将 wchar 值存储在双引号字符串中

python - 如何在 cython 中声明列表列表

c - 系统调用 open() 似乎在创建文件时随机设置文件权限

c - The C Programming Language(Second Edition) Exercise 1-1 4's Histogram' s Function中++cc[c]的作用是什么?