2012-03-02 12 views
4

私の最初の投稿ですので、簡単に取ってください。 :)私もPythonには少し新しかったですが、私はこれまでに見たものが好きです。私がやろうとしているのは、Python経由でレシートプリンタに印刷するためのCライブラリにアクセスすることです。私はctypesを使ってPythonでラッパーを作成していますが、2つの関数を除いてすべてがうまくいっています。ここに私たちの彼らのプロトタイプ:Python ctype help:Cの符号なしのcharポインタを使って作業する

int C56_api_printer_write(int printer, unsigned char * data, int size, unsigned long timeout_ms); 
int C56_api_printer_read(int printer, unsigned char * data, int size, unsigned long timeout_ms); 

私の問題はへの書き込みやctypesのを使用してunsigned char型ポインタからの読み取りです。私はPythonでビットマップファイルを読み込み、関数を書くために配列を渡す必要があります。あるいは、読み込みの場合、そのポインタを整数配列として読み込む必要があります。

私はこの数時間前からこの問題をぶつかってきたので、専門家がこれをどのように達成できるかの簡単な例を投稿して助けてくれることを願っていました。

ありがとうございました!

答えて

5

次はあなたを助けますか?

size = 
printer = 
timeout = 

data = (ctypes.c_ubyte * size)() # line 5 

C56_api_printer_read(printer, data, size, timeout) 

# manipulate data eg 
data[3] = 7 

C56_api_printer_write(printer, data, size, timeout) 

編集:5行目について

:またhttp://docs.python.org/library/ctypes.htmlセクション15.17.1.13および15.17.1.20を参照してください、それはあなたにエラーが発生しますか、私はあなたの質問を誤解場合は私に知らせてください。

(ctypes.c_ubyte * size) 

は、長さサイズのctypes配列を構成する関数を提供します。次に、この行では、引数なしの関数を呼び出して、ゼロで初期化します。

+0

Kyss、これは非常に近いです。正しい方向に押してくれてありがとう。私は以下の答えを投稿します。 – CharlieY

4

私はこれを終えることができました。ここに私のテストコードですと、この問題への完了を引き起こす:

マイtest.cのコード:

#include <stdio.h> 
int test(unsigned char *test, int size){ 
    int i; 
    for(i=0;i<size;i++){ 
     printf("item %d in test = %d\n",i, test[i]); 
    } 
} 
int testout(unsigned char *test, int *size){ 
    test[2]=237; 
    test[3]=12; 
    test[4]=222; 
    *size = 5; 
} 
main() { 
    test("hello", 5); 
    unsigned char hello[] = "hi"; 
    int size=0; 
    int i; 
    testout(hello,&size); 
    for(i=0;i<size;i++){ 
     printf("item %d in hello = %d\n",i, hello[i]); 
    } 
} 

私はCの関数をテストするためのメインを作成しました。ここでは、機能テストの出力があります:

item 0 in test = 104 
item 1 in test = 101 
item 2 in test = 108 
item 3 in test = 108 
item 4 in test = 111 
item 0 in hello = 104 
item 1 in hello = 105 
item 2 in hello = 237 
item 3 in hello = 12 
item 4 in hello = 222 

それから私は、共有用にコンパイルされ、それは、Pythonから使用することができます

gcc -shared -o test.so test.c 

そして、ここでは、私は私のPythonのコードのために使用したものです:

from ctypes import * 

lib = "test.so" 
dll = cdll.LoadLibrary(lib) 
testfunc = dll.test 
print "Testing pointer input" 
size = c_int(5) 
param1 = (c_byte * 5)() 
param1[3] = 235 
dll.test(param1, size) 
print "Testing pointer output" 
dll.testout.argtypes = [POINTER(c_ubyte), POINTER(c_int)] 
sizeout = c_int(0) 
mem = (c_ubyte * 20)() 
dll.testout(mem, byref(sizeout)) 
print "Sizeout = " + str(sizeout.value) 
for i in range(0,sizeout.value): 
    print "Item " + str(i) + " = " + str(mem[i]) 

そして出力:

Testing pointer input 
item 0 in test = 0 
item 1 in test = 0 
item 2 in test = 0 
item 3 in test = 235 
item 4 in test = 0 
Testing pointer output 
Sizeout = 5 
Item 0 = 0 
Item 1 = 0 
Item 2 = 237 
Item 3 = 12 
Item 4 = 222 

作品!

私の唯一の問題は、出力のサイズに基づいてc_ubyte配列を動的にサイズ変更することにあります。私はそれについて別の質問を投稿しました。

あなたのお役に立てありがとうございますKyss!

+0

*注:PyPyを使ってこのコードを実行すると、最初の関数のargtypesを宣言したいと思っています。私がそれらを宣言するとき、それは誤りです。だから私の解決策が100%正しいとは思わない。 – CharlieY

+0

あなたのバッファ 'hello'は3文字だけです(文字列の終端を含む)が、' testout'は5バイトに書き込みます。これはバッファオーバーランであり、メモリー内の "hi \ 0"ストリングの位置を超えてメモリーを破壊します。 –

+0

ヘルプマークありがとうございます。 – CharlieY

関連する問題