【问题标题】:passing a file descriptor to a C library function through ctypes on windows通过 Windows 上的 ctypes 将文件描述符传递给 C 库函数
【发布时间】:2012-02-08 20:03:44
【问题描述】:

我正在尝试通过 ctypes 将文件描述符传递给在 fd 上执行写入的 C 函数。在linux上它可以工作。在 Windows 上它没有,我不明白为什么(我没有作为 Windows 开发人员的经验)

//C func signature: 
void fun(struct bah *opaque, int fd)

来自python(细节省略):

mylib.fun.argtypes = [POINTER(bah), c_int]
fh = open(filename,'wb')
#doesn't work on windows, works on linux/unix
mylib.fun(some_ctypes_struct, fh.fileno())
#doesn't work on windows
mylib.fun(bah_struct, ctypes.cdll.msvcrt._open(filename,_O_FLAGS_MASK, ACCMASK)
#doesn't work
mylib.fun(bah_struct, os.open(...))

程序因断言_osfile(fh) & FOPEN 失败而在write()s 上死机

cl.exe: 16.00.40219.01 用于 x86 python 2.7.2 msc v.1500 32bit

我该怎么做?不,我不想将 open() 卸载到 lib。我想以一种与平台无关的安全方式传递已经打开的文件描述符。


附加信息,以防万一: 该库是 tinycdb,我使用简短的 cmake 规范和少量脏补丁将其快速移植到 Windows,以使 getopt 和 dll 导出工作。该库和 exe 工具按预期工作(经过测试)。 tinycdb 的 python ctypes 包装器按预期在 linux 上工作。 windows给了我眼球。他不会接受 fd 是一个有效的描述符,即使我在用它自己的 (msvcrt) _open libcall 打开它之后传递它。


当然,如果我在库中打开()/关闭()文件,但我无法更改 API,一切正常。

【问题讨论】:

  • Python 和您的 DLL 是否使用相同的 C 库 (msvcrt)? (dependencywalker.com 是一种检查方式。)

标签: python windows ctypes file-descriptor


【解决方案1】:

Windows 不像 Unix 那样使用文件描述,所以我假设文件描述符是由 C 运行时模拟的。如果您使用两个不同的 C 运行时(例如,如果您的 EXE 和 DLL 由不同的编译器编译,或者使用相同的编译器但具有不同的选项),那么每个运行时将有自己的“文件描述符仿真”,您可以t 将描述符从一个传递到另一个。

【讨论】:

  • python好像是用9.0编译的,我的dll用的是10.0。但是,我仍然将 OS 文件句柄和 C 运行时文件描述符视为不同的野兽。要么我同时使用 9.0 和 10.0 运行时,我的 fd“模拟器”不应该映射到同一个 OS 文件句柄吗?
  • 还是每个运行时都有自己的“描述符表”将 fds 映射到 OS 文件句柄?在这种情况下,错误是有意义的,因为我的 fd 在 crt90 的表中,而我正在 crt10 的表中搜索它。这是它的工作原理吗?谢谢jdigital!
  • 我想你已经回答了我的问题,但是“假设”装饰器让我要求更多,抱歉。
  • 最有可能的是“单独的描述符表”假设。顺便说一句,malloc 也有类似的问题:如果你有两个 malloc 实现(每个都有自己的堆),然后使用一个库中的 malloc 并从另一个库中释放,你就会遇到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
相关资源
最近更新 更多