私は Python 3.9、64 ビットを実行しており、VS 2022 を使用して libharu といくつかの拡張機能を libpng を含む DLL にコンパイルしました。 。最小限のコード調整を追加して VS ランタイム DLL (libhpdf) を見つけた後、DLL を Python にロードできます。 dll に依存しており、動作しているようです (バンドルには .py ファイルが 5 つだけあります) 進行状況を追跡するために、PTRACE を有効にして DLL を構築しました。 C デモもこの DLL を使用して動的に構築されており、すべて動作し、PDF を生成します。
バインディングに含まれる Python デモのサンプル arc_demo.py を実行しようとしています 同じ PDF ファイルを生成したい
ドキュメントを追加する行まではすべて正常に動作していると言えます。
pdf = HPDF_New (error_handler, NULL)
コンパイルされた C バージョンの例を使用して取得されたトレースと同様の出力。
しかし... var "pdf" は HP_AddPage() が期待するものではありません。次の呼び出しが発行されるときにページが追加されるためです。
page = HPDF_AddPage (pdf)
私はこれを見つけました:
**ctypes.ArgumentError: パラメータ 1: <class 'OverflowError'>: int が長すぎて変換できません**
これは、32 ビットのみで構築およびテストされている元のバインディングと関係があるのではないかと思います。もう 1 つの疑いがあるのは、移植された ctypes です。
それでは今、主に hpdf.py のバインディングを変更しています。
現在、Python と DLL の相互通信に苦労しており、ctypes が期待どおりに処理するかどうかを確認しています。 byref
を使用して *pdf * を c_void_p
に変換します...うまくいきません。呼び出しが ref(c_void_p(pdf)) 経由で行われた場合、エラーは解消されますが、HPDF_Doc 構造体のコンテンツに適切にアクセスできません。
###助言がありますか?お手伝いできるでしょうか? C ベースの DLL を使用して Python をデバッグするための比較アプローチ?
PS: クラスは最終的には、Haru PDF 内部用に作成される予定です。ただし、これは Python サンプルをエラーなしで実行できるようになった後に発生します。
正解
のctypesインターフェイスがすべての関数に対して定義されていません
.argtypes。 64 ビットのハンドルとポインターの場合、各関数に正しいパラメーターの型を定義することが特に重要です。
windll から
cdll インターフェイスへの切り替えで示されているように、元の開発者はこれを理解していなかった可能性があります。
windll
__stdcall 呼び出し規則を使用し、パラメータ サイズの知識が必要です。
たとえば、
hpdf_doc
hpdf_handle として定義され、これは
ctypes.c_void_p として定義されます。これは、64 ビット オペレーティング システム上の 64 ビット ポインターです。
hpdf_new および
hpdf_addpage は次のように定義されます:
リーリー
ctypes
hpdf_addpage に渡される引数は
c_int であると仮定します。ハンドル値が 32 ビットを超えているため、エラーが発生します。理想的には、
ctypes が型チェックを行い、引数を Python オブジェクトから C 型に正しくマーシャリング (変換) できるように、すべての関数が引数の型を明示的に宣言する必要があります。次に例を示します。
リーリー
パラメータの型は ctypes
型に基づく必要があることに注意してください。引数を注意深く追跡し、関数ごとに
を宣言する必要があります。
以上がLibHaru の Python バインディングを Python 3.9 (64 ビット) に更新しようとした人はいますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。