2013-07-01 1 views
1

У меня есть C-программа, которая приобретает изображение с моей камеры и записывает двоичные данные в файл.Возможно ли записать данные из файла void_pointer в файл в python ctypes

Я (до сих пор безуспешно) пытался написать скрипт python для имитации C-кода.

Пример ctypes Python, как представляется, выполняется без ошибок. UNTIL Я пытаюсь записать его в файл. Другими словами, в Python fwrite не может записать данные в файл в этом экземпляре. fwrite возвращает значение 0, что указывает на то, что были написаны 0.

Итак, я спрашиваю следующее: Поскольку у меня есть внешний с-функция, которая читает двоичные данные, предположительно, в какой-то буфер в памяти, возможно, что экземпляр Python ctypes просто не имеет читать доступ к этой ячейке памяти? И если это так, возможно ли для python ctypes получить разрешение, необходимое для доступа к соответствующей области в памяти?

Для справки, я включил (как ожидалось) упрощенный пример C, за которым следует пример cythips Python ниже, который открывается и создает соответствующий файл, но не записывает на него.

//Data Saving Sample 
//The sample will open the first camera attached 
//and acquire 3 frames. The 3 frames will be saved 
//in a raw format and can be opened with applications 
//such as image-j 

#define NUM_FRAMES 3 
#define NO_TIMEOUT -1 

#include "stdio.h" 
#include "picam.h" 
#include <iostream> 
using namespace std; 

int main() 
{ 

    // The following structure contains the image data 
    AvailableData data; 

    int readoutstride = 2097152; 
    FILE *pFile; 


    Acquire(NUM_FRAMES, NO_TIMEOUT, &data, &errors); 

    pFile = fopen("sampleX3.raw", "wb"); 
    if(pFile) 
    { 
     fwrite(data.initial_readout, 1, (NUM_FRAMES*readoutstride), pFile); 
     fclose(pFile); 
    } 

} 

А вот моя версия Python:

""" Load the picam.dll """ 
picamDll = 'DLLs/Picam.dll' 
picam = ctypes.cdll.LoadLibrary(picamDll) 

libc = ctypes.cdll.msvcrt 
fopen = libc.fopen 

data = AvailableData() 
readoutstride = ctypes.c_int(2097152) 

""" 
This is the C-structure form from the provided header file, followed by the Python syntax for creating the same structure type 
typedef struct AvailableData 
{ 
    void* initial_readout; 
    int64 readout_count; 
} AvailableData; 

class AvailableData(ctypes.Structure): 
    _fields_ = [("initial_readout", ctypes.c_void_p), ("readout_count",ctypes.c_int64)] 
""" 

""" 
Simplified C-Prototype for Acquire 

Acquire(
int64      readout_count, 
int      readout_time_out, 
AvailableData*   available); 
""" 
picam.Acquire.argtypes = int64, int, ctypes.POINTER(AvailableData) 

picam.Acquire.restype = int 

print picam.Acquire(3, -1, ctypes.byref(data), ctypes.byref(errors)) 

""" Write contents of Data to binary file """ 
fopen.argtypes = ctypes.c_char_p, ctypes.c_char_p 
fopen.restype = ctypes.c_void_p 

fwrite = libc.fwrite 
fwrite.argtypes = ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p 
fwrite.restype = ctypes.c_int 

fclose = libc.fclose 
fclose.argtypes = ctypes.c_void_p, 
fclose.restype = ctypes.c_int 

fp = fopen('PythonBinOutput.raw', 'wb') 
print 'fwrite returns: ',fwrite(data.initial_readout, 3*readoutstride.value, 1, fp) 
fclose(fp) 
+0

Было бы гораздо лучше, если вы раздели все несвязанный материал Picam, что делает его для людей сложно тестировать и отлаживать ваш код. См. Http://sscce.org для некоторых идей о том, что делает хороший пример кода для вопроса. – abarnert

+0

@abarnert согласился - просто сделал некоторую очистку спасибо – Joe

+0

Между тем, что именно находится в readoutstride.value? Вы уверены, что это не 0? – abarnert

ответ

0

Создать массив для использования с обычным файлом Python. Например:

Получить пустой указатель:

class AvailableData(Structure): 
    _fields_ = [ 
     ("initial_readout", c_void_p), 
    ] 

cglobals = CDLL(None) # POSIX dlopen 
cglobals.malloc.restype = c_void_p 

size = 100 # 3 * readoutstride.value 
data = AvailableData(cglobals.malloc(size)) 

Теперь использовать его как массив:

buf = (c_char * size).from_address(data.initial_readout) 
with open('PythonBinOutput.raw', 'wb') as f: 
    f.write(buf)