我需要从C库中公开一个类似文件的对象,我用Cython模块包装它.我想重用python的通用io代码,比如缓冲,readline()等.
新的IO模块似乎正是我需要的,但实际上从Cython中使用它似乎是非平凡的,我尝试了几个方法:
我的代码在一个继承自IO.RawIOBase的cdef类中 - 这失败了,因为cdef类只能从其他cython cdef类继承,而IO是"raw"C.
我的代码在cdef类中,另一个(非cdef)类继承了我的cdef类和RawIOBase - 失败了"TypeError:多个base有实例布局冲突"
我的代码在一个(非cdef)类中继承自RawIOBase - 这是有效的,但我放弃了在类中存储我的c级(我需要与底层库交谈)的能力,所以我需要一个make围绕它的cdef包装并将其存储为成员...这看起来像一团糟.
我的cdef类中的代码不继承(Raw)IOBase而是重新实现它的功能,Python代码将我的对象包装在BufferedReader/BufferedWriter中 - 这个似乎比以前的选项更有效.
我的问题:
1)我错过了什么并在这里重新发明轮子?
2)我需要实现的IOBase的确切内容是什么,以保持BufferedReader/Writer在我当前和未来版本的python中对我的对象满意?这记录在哪里?
3)在Python是纯Python的python 2.6中如何工作?我想性能会受到影响,但它会起作用,对吗?
我确定这是在某处记录但我找不到它......
我的代码是从另一个库(我无法修改)获取python对象,我需要调用一些win32 api函数.
Python返回的东西不是file.fileno()的os级句柄,我的猜测是它给了MSVCRT的fileno.
>>> ctypes.windll.kernel32.CreateFileA('test',0x80000000L,1,None,3,0,0)
1948 # <- HANDLE
>>> file('test','r').fileno()
4 # <- not a HANDLE
Run Code Online (Sandbox Code Playgroud)
如何将其转换为真正的win32句柄?
我有一个用cython编写的库,它包装了一个C库,我将一些c字符串暴露给python代码.这些字符串很大,而且是静态的(不能释放它们)所以只是从它们那里制作一个python字符串(这就是副本)不是一个选项 - 我得到了OOM错误.
我有代码工作python 2.x目前使用旧的缓冲API,看起来或多或少像:
def get_foo():
return PyBuffer_FromMemory(c_foo_ptr,c_foo_len)
Run Code Online (Sandbox Code Playgroud)
这对于python 2.x来说是有效的(tm),但是旧的缓冲API在3.x中消失了,我无法弄清楚如何使用新的缓冲API.
我看到PyMemoryView_FromBuffer和PyBuffer_FillInfo结合起来应该做同样的事情,但PyBuffer_FillInfo想要一个对我来说不存在的对象(它只是一个模块级函数),制作一个虚拟对象并传递它只是给了我一个段错误,所以我想这个对象应该以某种方式支持缓冲区......但它的文档记录在哪里?
进一步尝试使用内存视图,它们根本不会看起来或充当字符串(或字节),因此我必须重写所有的python代码或以某种方式重新创建该功能.
我错过了什么吗?有没有一种简单的方法来替换py3k中的PyBuffer_FromMemory?
注意:我正在使用cython,但这是原始c-api的东西,所以你可以在不涉及cython的情况下回答它.
例如,给定
object ~ {
def foo = ???
}
Run Code Online (Sandbox Code Playgroud)
我如何访问该方法?
这些都不奏效:
~.foo
`~`.foo
Run Code Online (Sandbox Code Playgroud)
两个编译器抱怨"非法启动简单表达".
是的,我知道我可能不应该命名类"〜",但标准库和其他一些库都有,有时你需要使用它们.
补充:看着sschaef的回答我试过了
$tilde.foo
Run Code Online (Sandbox Code Playgroud)
这确实有效.不确定是否有意或只是这些名称如何转换为JVM标识符的实现细节.这是否适用于其他scala(例如Scala.js)?
我会稍微公开一下,看看也许有人会更广泛的回答.