组合两个独立的C语言模块,我必须将一个函数指针存储在一个双数组中(将其传递给模块),然后将其转换回来。 我试着坚持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 !
谢谢!
答案 0 :(得分:0)
将函数指针转换为任何其他指针类型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
的地址重新解释为指向空格指针的指针。
cdef void* ptr2 = Pptr2[0]
您取消引用该地址。 ptr2
包含doubleArrayStorage
的第一个元素,您假装的是void*
。实际上它是你之前读过的任意内存的内容。
cdef TEST mytest2 = <TEST> ptr2
mytest2() #SEGMENTATION FAULT !
您将该任意内存位的内容用作函数指针并尝试执行它。
总之,我不相信有任何方法可以做你在C中安全地做的事情(这意味着Cython也不能这样做)。