我试图使用Win32 msvcrt.dll
打开标准输出并打印出一些任意字符串。请记住,我不 * 不 * 想使用print
或msvcrt
和os
库。
我尝试使用_fdopen
和_fputs
,但总是得到OSError: exception: access violation reading 0x0000000036B5FAA8
。我认为问题是在python中不能有FILE*
,它通过ctypes
转换为int
,但我不知道如何转换该内存地址(int)转换成一个实际的指针传递给函数。有可能我错了,我做的其他事情是不好的。
代码:
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
,但由于内存分配的差异,每次运行都会略有变化)
1条答案
按热度按时间f0ofjuux1#
我需要明确地将
_fdopen
的返回类型指定为ctypes.c_void_p
(未指定类型的指针),这样可以成功地工作。看起来Python试图猜测返回类型(并假设它不是指针),它会猜错并给予错误的结果,这会导致
_fdopen
函数试图写入不正确的位置,从而导致越界写入。