繁体   English   中英

如何从 Python 打开 Win32 文件*

[英]How to open a Win32 FILE* from Python

我正在尝试使用 Win32 msvcrt.dll打开标准 output 并打印出一些任意字符串。 请记住,我不想使用printmsvcrtos库。

我尝试使用_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)
  )
)

这是我正在尝试做的,但使用的msvcrtos 它完美地工作:

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.TextIOWrapperfd导致一些巨大的数字(十六进制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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM