我想重开stdin和stdout(也许stderr当我在它)的文件句柄,从而使未来的呼叫printf()或putchar()还是puts()会去到一个文件,以及未来的呼叫getc()和这种将来自一个文件.
1)我不想永久丢失标准输入/输出/错误.我可能希望稍后在程序中重用它们.
2)我不想打开新的文件句柄,因为这些文件句柄必须要么传递很多,要么全局传递(不寒而栗).
3)如果我无法帮助,我不想使用任何open()或fork()其他系统相关的功能.
所以基本上,这样做是否有效:
stdin = fopen("newin", "r");
Run Code Online (Sandbox Code Playgroud)
而且,如果确实如此,我怎样才能得到原来的价值stdin?我是否必须将其存放在一个FILE *以后才能将其取回?
我使用python lib导入一个在stdout上打印的C共享库.我想要一个干净的输出,以便与管道一起使用或重定向文件.打印是在python之外的共享库中完成的.
一开始,我的方法是:
# file: test.py
import os
from ctypes import *
from tempfile import mktemp
libc = CDLL("libc.so.6")
print # That's here on purpose, otherwise hello word is always printed
tempfile = open(mktemp(),'w')
savestdout = os.dup(1)
os.close(1)
if os.dup(tempfile.fileno()) != 1:
assert False, "couldn't redirect stdout - dup() error"
# let's pretend this is a call to my library
libc.printf("hello world\n")
os.close(1)
os.dup(savestdout)
os.close(savestdout)
Run Code Online (Sandbox Code Playgroud)
第一种方法是半工作:
- 由于某种原因,它在移动stdout之前需要一个"print"语句,否则总是打印hello word.因此,它将打印一个空行而不是库通常输出的所有模糊.
- 更令人讨厌,重定向到文件时失败:
$python test.py > foo && cat foo
hello world …Run Code Online (Sandbox Code Playgroud) 由于某些其他原因,我使用的c ++共享库将一些文本输出到标准输出.在python中,我想捕获输出并保存到变量.关于重定向标准输出有许多类似的问题,但在我的代码中不起作用.
示例:禁止在库外调用模块的输出
1 import sys
2 import cStringIO
3 save_stdout = sys.stdout
4 sys.stdout = cStringIO.StringIO()
5 func()
6 sys.stdout = save_stdout
Run Code Online (Sandbox Code Playgroud)
在第5行,func()将调用共享库,共享库生成的文本仍然输出到控制台!如果改变func()打印"你好",它的工作原理!
我的问题是:
我有以下我想用Python编写的shell脚本(当然grep .实际上是一个更复杂的命令):
#!/bin/bash
(cat somefile 2>/dev/null || (echo 'somefile not found'; cat logfile)) \
| grep .
Run Code Online (Sandbox Code Playgroud)
我尝试了这个(cat logfile无论如何都缺少相同的东西):
#!/usr/bin/env python
import StringIO
import subprocess
try:
myfile = open('somefile')
except:
myfile = StringIO.StringIO('somefile not found')
subprocess.call(['grep', '.'], stdin = myfile)
Run Code Online (Sandbox Code Playgroud)
但是我得到了错误AttributeError: StringIO instance has no attribute 'fileno'.
我知道我应该使用subprocess.communicate()而不是StringIO来向grep进程发送字符串,但我不知道如何混合字符串和文件.
我正在使用ctypes用Python包装一个C库(我已经控制过).我想用声明包装一个C函数:
int fread_int( FILE * stream );
Run Code Online (Sandbox Code Playgroud)
现在; 我想在python中打开文件,然后使用Python文件对象(以某种方式??)来访问底层的FILE*对象并将其传递给C函数:
# Python
fileH = open( file , "r")
value = ctypes_function_fread_int( ????? )
fileH.close()
Run Code Online (Sandbox Code Playgroud)
Python文件< - > FILE*映射是否可能?
乔金 -
我正在尝试将printf函数的输出重定向到Windows上的文件.我正在使用python3的ctypes来调用函数.我的代码是:
import os, sys
from ctypes import *
if __name__ == '__main__':
print("begin")
saved_stdout=os.dup(1)
test_file=open("TEST.TXT", "w")
os.dup2(test_file.fileno(), 1)
test_file.close()
print("python print")
cdll.msvcrt.printf(b"Printf function 1\n")
cdll.msvcrt.printf(b"Printf function 2\n")
cdll.msvcrt.printf(b"Printf function 3\n")
os.dup2(saved_stdout, 1)
print("end")
Run Code Online (Sandbox Code Playgroud)
但是当我从Eclipse运行代码时,我在屏幕上得到以下内容:
begin
end
Printf function 1
Printf function 2
Printf function 3
Run Code Online (Sandbox Code Playgroud)
...以及TEST.txt中的以下内容
python print
Run Code Online (Sandbox Code Playgroud)
当我从cmd运行它时,这就是屏幕上的内容:
begin
end
Run Code Online (Sandbox Code Playgroud)
..这是在TEST.txt中:
python print
Run Code Online (Sandbox Code Playgroud)
当我评论出第二个dup2()陈述时,例如
import os, sys
from ctypes import *
if __name__ == '__main__':
print("begin")
saved_stdout=os.dup(1)
test_file=open("TEST.TXT", "w")
os.dup2(test_file.fileno(), 1)
test_file.close()
print("python print")
cdll.msvcrt.printf(b"Printf function 1\n") …Run Code Online (Sandbox Code Playgroud) 以下代码适用于Python 2:
from ctypes import *
## Setup python file -> c 'FILE *' conversion :
class FILE(Structure):
pass
FILE_P = POINTER(FILE)
PyFile_AsFile = pythonapi.PyFile_AsFile # problem here
PyFile_AsFile.argtypes = [py_object]
PyFile_AsFile.restype = FILE_P
fp = open(filename,'wb')
gd.gdImagePng(img, PyFile_AsFile(fp))
Run Code Online (Sandbox Code Playgroud)
但在Python 3中,pythonapi中没有PyFile_AsFile.
代码是testPixelOps.py之外的代码.
是否可以从C dll函数调用Python 函数?
我们考虑这个C函数:
void foo( void (*functionPtr)(int,int) , int a, int b);
Run Code Online (Sandbox Code Playgroud)
在Python上,我想调用foo并将回调设置为Python函数:
def callback(a, b):
print("foo has finished its job (%d, %d)" % (a.value,b.value))
dll.foo( callback, c_int(a), c_int(b) )
Run Code Online (Sandbox Code Playgroud)
不幸的是,ctypes文档对这个主题非常清楚,上面的代码不起作用.
我正在使用 python ctypes 和 libc 与供应商提供的 DLL 文件进行交互。DLL 文件的目的是从相机获取图像。
图像采集似乎运行没有错误;我遇到的问题是访问数据。
图像采集函数将 ctypes.c_void_p 作为图像数据的参数。
简化如下:
"""
typedef struct AvailableData
{
void* initial_readout;
int64 readout_count;
} imageData;
"""
class AvailableData(ctypes.Structure):
_fields_ = [("initial_readout", ctypes.c_void_p),
("readout_count", ctypes.c_longlong)]
"""
Prototype
Acquire(
CamHandle camera,
int64 readout_count,
int readout_time_out,
AvailableData* available,
AcquisitionErrorsMask* errors );
"""
>>> imageData = AvailableData()
>>> Acquire.argtypes = CamHandle, ctypes.c_longlong, ctypes.c_int,
ctypes.POINTER(AvailableData), ctypes.POINTER(AcquisitionErrorsMask)
>>> Acquire.restype = ctypes.c_void_p
>>> status = Acquire(camera, readout_count, readout_time_out, imageData, errors)
Run Code Online (Sandbox Code Playgroud)
我不完全理解该函数在做什么,因为在我运行该函数后,它imageData.initial_readout似乎是一个类型“long”(甚至不是 ctypes.c_long:只是“long”)。然而,它也有一个与之相关的价值。我假设这是存储数据的起始地址。
>>> type(imageData.initial_readout)
<type …Run Code Online (Sandbox Code Playgroud) python ×8
ctypes ×6
c ×1
c++ ×1
ffi ×1
fwrite ×1
libc ×1
python-2.x ×1
python-3.x ×1
redirect ×1
stdio ×1
subprocess ×1
windows ×1