3

私は暗号に関連するプロジェクトを行っています。でコードをビルドしていますpython。ただし、暗号関数はPBC計算に C ライブラリを使用します。したがって、適切な関数を含む C プログラムを作成し、それを共有ライブラリとしてコンパイルしました。を使用してライブラリをインポートしますctypes。これまでのところ、すべて順調です。

私が今直面している問題は、unsigned char宣言された変数をライブラリでグローバル変数として取得する必要があり、Python ソケットを介して別の受信 Python ソケットに送信する必要があることunsigned charです。

今、unsigned charライブラリから を取得しようとすると、

ibc = cdll.LoadLibrary('./libibc.so.1.0.1')
strin = 'some string'
ibc.init_pairing(1, 1, 1)# Initializing the lib
ibc.read_share()
id_str = (c_char * 40)()
id_str.value = strin
ibc.hash_id_s(id_str)    # Passing a char to a function

hsid = (c_ubyte * 1000)()
hsid = c_ubyte.in_dll(ibc, "hid")
ibc.gen_privatekey(hsid, 1, 3) #pass unsigned char to function

最後の行は、セグメンテーション違反で終わります。そこでgen_privatekey、次のコードを使用して、c 自体から関数を呼び出しました。

int genprkey(){
    unsigned char key[100];
    element_to_bytes(key, pks);
    gen_privatekey(key, 1, 2);
}

次に、次を使用して python からこの関数を呼び出します。

ibc.genprkey()

そしてプログラムは成功します。

問題

上記の関数はunsigned char、別のグローバル変数にも格納される を生成します。このように変数を取得しようとしました:

hsidp = (c_char_p)()
hsidp = c_char_p.in_dll(ibc, "hid")

Pythonインタープリターで上記のコードを試しました。入力すると:

hsidp

出力は次のとおりです。

c_char_p(10598250801977757708)

しかし、私が入力すると:

hsidp.value

を取得しsegmentation fault (core dumped)ます。変数の処理方法が正しくないと思われます。Python で変数としてを取得したら、unsigned charそれを別のソケットにメッセージとして送信し、それを読み取ってunsigned char同じライブラリに an として渡す必要があります。

これがどのように可能になるかはわかりません。助けてください

4

1 に答える 1

2

共有ライブラリの配列にアクセスする方法は次のとおりです。

ダミー ライブラリ:

>>> from ctypes import *
>>> import os

>>> open('lib.c', 'w').write(
...   'unsigned char data[] = {0, 1, 2, 3};\n')
>>> ret = os.system('gcc -shared -o lib.so lib.c')

ライブラリをロードし、長さ 4 の配列にアクセスします。unsigned char

>>> lib = CDLL('./lib.so')
>>> data = (c_ubyte * 4).in_dll(lib, 'data')
>>> list(data)
[0, 1, 2, 3]

また、c_char_pポインタであり、配列の最初の 4 または 8 バイトからそれを取得すると、誰がどこを知っているかがわかるため、逆参照しようとすると segfault が発生する可能性があります。hsidpさらに、以下の最初のステートメントは、2 番目のステートメントで再割り当てするとすぐに解放されるポインターをインスタンス化します。

hsidp = (c_char_p)()   
hsidp = c_char_p.in_dll(ibc, "hid")

同様に、以下の最初の行は長さ 1000 の配列を作成し、それを破棄します。どうしてか分かりません。次に、ライブラリから 1 バイトを取得します。

hsid = (c_ubyte * 1000)()
hsid = c_ubyte.in_dll(ibc, "hid")

バイトまたはバイトの配列が必要ですか? どのくらいの長さですか?またはgen_privatekey、ヌル終了文字列へのポインターが必要ですか?


string_atPythonstrオブジェクトを取得するために使用できます。

>>> hid = (c_ubyte * 24)(*map(ord, "This is a test."))
>>> string_at(hid, 24)
'This is a test.\x00\x00\x00\x00\x00\x00\x00\x00\x00'

c_charまたは、バッファから配列を作成することもできます(または、c_ubyte配列の代わりに最初からそれを使用することもできます)。

>>> (c_char * 24).from_buffer(hid).value
'This is a test.'

配列は、Pythonオブジェクトを返すおよび記述子があるため、文字列を操作するc_charのに便利です。これらの記述子を使用すると、文字列をバッファーに書き込むこともできます。valuerawstr

>>> hid = (c_char * 24)()
>>> hid.value = 'This is a test.'
>>> hid.value
'This is a test.'
于 2013-03-09T10:12:53.370 に答える