【问题标题】:conflict between cython and ctypes using sizeof function使用 sizeof 函数的 cython 和 ctypes 之间的冲突
【发布时间】:2017-03-13 06:00:18
【问题描述】:

我在 some.py 文件中定义了一个类 SomeClass(ctypes.Structure) 并将其导入到 some.pyx 文件中,如下所示:

from ctypes import memset, addressof, sizeof
from some import SomeClass
someInstance = SomeClass()
memset(addressof(someInstance), 0, sizeof(SomeClass)) 

但无论 SomeClass 中有多少个字段,sizeof 函数总是返回 8。 我认为 sizeof 函数是 cython 中的内置函数,而不是 ctypes 的。如果我这样导入,SomeClass 的大小是正确的:

from ctypes import memset, addressof, sizeof as csizeof
memset(addressof(someInstance), 0, csizeof(SomeClass)) 

【问题讨论】:

  • 看来你已经解决了问题,请问有什么问题?
  • 我的问题是:为什么我声明'from ctypes import sizeof'没有用?它不应该使用 cython 中的默认 sizeof。

标签: cython ctypes


【解决方案1】:

您看到的行为与调用 cdef 函数的行为一致,是 Cython 唯一明智的做法。

与 C 交互时(例如调用外部模块和调用 cdef 函数)Cython 决定在编译时调用哪个函数:

cdef a():
   print("Hi")

from some_module import a
a() # will print Hi - this is decided by the functions Cython knows about when it compiles

import 语句在运行时进行评估。 Cython 无法在编译时知道它们,因为它们定义的变量可以随意重新分配。

from some_module import a_function
del globals()['a_{}'.format('func')+'tion']
a_function() # no longer defined here, but how can Cython know?

如果 Cython 尝试计算 cdef 函数是否已被 globals 中的某些内容(即已导入的内容)覆盖,那么您将失去 Cython 的大部分速度增益 - 否则快速 C-只有代码需要相当昂贵的字典查找:

 cdef char* a = <char>malloc(sizeof(char))

会被翻译成无意义的东西

 # pseudocode!
 try:
     char_tmp = globals()['char']
 except KeyError:
     char_tmp = built_in_char
 try:
     sizeof_tmp = globals()['sizeof']
 except KeyError:
     sizeof_tmp = built_in_sizeof

 try:
     malloc_tmp = globals()['malloc']
 except KeyError:
     malloc_tmp = built_in_malloc
 a = <char>malloc_tmp(sizeof_tmp(char_tmp))

此外,这个简单的语句不能在多线程代码中使用,因为它现在依赖于一次只能运行一个线程的 Python 解释器。

因此,唯一不完全破坏 Cython 的解决方案是在编译时选择使用 C sizeof,并失去通过导入来覆盖它的能力。


额外说明:实际上,C sizeof 在编译时被评估为常量,而不是在运行时调用,因此您的使用更没有意义。

【讨论】:

  • 谢谢,你的回答很清楚。此外,SomeClassctypes.Structure 的子类。我只能使用ctypes.sizeof 来获取它的大小,而不是 C sizeof。或者,我怎样才能使用快速的 C sizeof 来做到这一点?另外,不知ctypes.sizeof是不是很慢,不是用C代码实现的?
  • 如你所说,你应该使用ctypes.sizeof 代替someClass。这是你应该只需要做一次的事情(sizeof(someClass) 在同一台计算机上总是相同的)所以不必担心速度。
猜你喜欢
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多