1

私は以下のようなC関数を持っています:

char* hash_id_G1(char *str){
char hash[20];
...
return hash;
}

私が必要としているのは、char配列を取り込んで、char配列またはcharへのポインターを返す、ここにあるようないくつかの関数です。

これらを共有にコンパイルし、ctypesを使用してPythonにインポートします。

これは私がこれまでに行った方法です:

from ctypes import *
ibc = cdll.LoadLibrary('./libibc.so.1.0.1')
strin = 'sometext to hash'
ids = (c_char * 40)()
ids.value = strin
hash = c_char_p
hash_id = ibc.hash_id_G1
hash_id.restype = c_char_p
hash = hash_id(ids)

ライブラリはうまく機能しますが、restypeを設定できません。そうすると、コードがセグメンテーション違反でクラッシュします。

Pythonからcライブラリの関数を1つずつ呼び出す必要があります。関数は通常、暗号化を返します。これらの関数を定義して、ctypeインターフェイスから文字列を受け入れ、保存可能な形式で暗号化を返すようにするにはどうすればよいですか?

どんな助けでも大歓迎です。私はCポインタと関連するものに非常に弱いです。前もって感謝します

アップデート

セグメンテーション違反は、コンパイルエラーが原因でした。関数がunsignedcharを返す場合、Cでctype変数をどのように宣言する必要がありますか?

4

1 に答える 1

2

そのように引数を渡さないでください。エラーが発生しやすく、慣用的ではありません (したがって、読みにくい)。次の操作を実行できます。

from ctypes import *

ibc = cdll.LoadLibrary('./libibc.so.1.0.1')
ibc.hash_id_G1.restype = c_char_p
hash = ibc.hash_id_G1(c_char_p('sometext to hash'))

それとは別に、ローカル変数へのポインターを返すため、未定義の動作に対処しています。ローカル変数は、それらが宣言されたスコープ内にのみ存在します。その範囲外でそれらにアクセスすると、偽の結果を返すことからセグメンテーション違反まで何でもできます。コンパイラ オプションを変更することでコードの segfault が発生しなくなった場合、それは純粋な運によるものです。

それを修正する方法は、配列を宣言することですstatic。したがって、配列の範囲外でも持続しhash_id_G1ます...

char *hash_id_G1(char *str)
{
    static char hash[20];
    ...
    return hash;
}

...またはメモリを明示的に割り当てる。

char *hash_id_G1(char *str)
{
    char *hash = malloc(20);
    ...
    return hash;
}

最初のオプションはスレッドセーフではありません (アプリケーションにとっては問題にならないかもしれませんfree)。

新しい質問については、ドキュメントをお読みください。

于 2013-03-04T15:23:03.030 に答える