[英]How to open a Win32 FILE* from Python
我正在尝试使用 Win32 msvcrt.dll
打开标准 output 并打印出一些任意字符串。 请记住,我不想使用print
或msvcrt
和os
库。
我尝试使用_fdopen
和_fputs
但我一直收到OSError: exception: access violation reading 0x0000000036B5FAA8
。 我认为问题是我不能在 python 中有一个FILE*
并且它通过ctypes
转换为int
但我不知道如何将 memory 地址(int)转换为实际指针以传递给 function。它是可能我错了,我做的其他事情不好。
代码:
c = __import__('ctypes.util')
c_lib = c.CDLL(c.util.find_library('msvcrt'))
fptr = c_lib._get_osfhandle(
c.cast(
1,
c.POINTER(c.c_int),
)
)
realf = c_lib._open_osfhandle(
fptr,
c.cast(
8,
c.POINTER(c.c_int),
)
)
fd = c_lib._fdopen(realf,
c.cast(
b'w',
c.POINTER(c.c_char),
)
)
c_lib.fputs(
c.cast(
b'Hello msvcrt!',
c.POINTER(c.c_char),
),
fd
)
c_lib._flushall()
c_lib._close(realf)
c_lib._exit(
c.cast(
0,
c.POINTER(c.c_int)
)
)
这是我正在尝试做的,但使用的msvcrt
和os
。 它完美地工作:
import msvcrt, os
fptr = msvcrt.get_osfhandle(1)
realf = msvcrt.open_osfhandle(fptr, os.O_APPEND)
fd = os.fdopen(realf, 'w')
fd.write('hello')
fd.flush()
os.close(realf)
我怎样才能做同样的事情,但采用以前代码的格式? 我尝试查看 CPython 源代码以了解os.fdopen
在内部做了什么,但是在那里找不到任何东西(太多的嵌套和 github 的搜索支持很差)。 在打开fd
之前,代码的工作方式相同。 然而, os.fdopen
返回一个IO.TextIOWrapper
而fd
导致一些巨大的数字(十六进制36B5FAA8
但由于 memory 分配差异每次运行略有变化)
我需要将_fdopen
的返回类型明确指定为成功运行的ctypes.c_void_p
(具有未指定类型的指针)。
# Specify the return type
c_lib._fdopen.restype = c.c_voidp
fd = c_lib._fdopen(realf,
c.cast(
b'w',
c.POINTER(c.c_char),
)
)
似乎 Python 试图猜测返回类型(并假设它不是指针),它会猜错并给出错误的结果,这将导致_fdopen
function 尝试写入不正确的位置,从而导致输出越界写入。
问题未解决?试试以下方法:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.