問題內(nèi)容
我正在運行 Python 3.9,64 位,并已使用 VS 2022 將 libharu 和一些擴展編譯到 DLL 中,包括 libpng。在添加最少的代碼調(diào)整以查找 VS 運行時 DLL(libhpdf)后,DLL 可以加載到 Python 中。 dll 依賴,并且似乎可以工作(綁定中只有 5 個 .py 文件)
我已經(jīng)構(gòu)建了啟用 PTRACE 的 DLL,以跟蹤進度。還使用該 DLL 動態(tài)構(gòu)建了 C 演示,它們都可以工作,生成 PDF。
我正在嘗試運行綁定中包含的 python 演示示例,arc_demo.py
希望生成相同的 PDF 文件
我可以說一切正常,直到添加文檔的行:
pdf = HPDF_New (error_handler, NULL)
與使用示例的編譯 C 版本獲得的跟蹤類似的輸出。
但是… var“pdf”不是 HP_AddPage() 所期望的,因為在發(fā)出下一個調(diào)用時,要添加頁面
page = HPDF_AddPage (pdf)
我遇到了這個:
**ctypes.ArgumentError:參數(shù) 1::int 太長,無法轉(zhuǎn)換**
我認為這可能與原始綁定僅使用 32 位構(gòu)建和測試有關(guān)。另一個嫌疑點是移植的 ctypes。
所以現(xiàn)在我正在修改綁定,主要是hpdf.py。
目前,正在與 Python 到 DLL 的相互通信進行斗爭,檢查 ctypes 是否按預(yù)期處理事情。使用 byref
,將 *pdf * 轉(zhuǎn)換為 c_void_p
,…沒有運氣。如果調(diào)用是通過 ref(c_void_p(pdf)) 完成的,我會消除錯誤,但無法正確訪問 HPDF_Doc 結(jié)構(gòu)的內(nèi)容
有什么建議嗎?你可能會提供幫助嗎?使用基于 C 的 DLL 調(diào)試 Python 的對比方法?
謝謝,
伊格納西奧
PS:最終將為 Haru PDF 內(nèi)部結(jié)構(gòu)編寫類。但這會在我能夠無錯誤地運行 python 示例之后發(fā)生。
正確答案
if/python/hpdf.py
中的ctypes
接口沒有為所有函數(shù)定義.argtypes
。對于 64 位句柄和指針來說,為每個函數(shù)定義正確的參數(shù)類型尤其重要。最初的開發(fā)人員可能不明白這一點,如從 windll
轉(zhuǎn)換為 cdll
接口所示。 windll
使用 __stdcall
調(diào)用約定并需要知道參數(shù)大小。
例如,hpdf_doc
被定義為 hpdf_handle
,它被定義為 ctypes.c_void_p
。這是 64 位操作系統(tǒng)上的 64 位指針。 hpdf_new
和 hpdf_addpage
定義為:
#hpdf_doc hpdf_new (hpdf_error_handler user_error_fn, void *user_data) hpdf_new=haru.hpdf_new hpdf_new.restype=hpdf_doc #hpdf_page hpdf_addpage (hpdf_doc pdf) hpdf_addpage=haru.hpdf_addpage hpdf_addpage.restype=hpdf_page
登錄后復(fù)制
ctypes
假設(shè)傳遞給 hpdf_addpage
的參數(shù)是 c_int
因為 to 沒有 argtypes。句柄值是 >32 位,因此出現(xiàn)錯誤。理想情況下,所有函數(shù)都應(yīng)顯式聲明其參數(shù)類型,以便 ctypes
可以進行類型檢查并正確地將參數(shù)從 python 對象編組(轉(zhuǎn)換)為 c 類型,例如:
HPDF_AddPage.argtypes = HPDF_Doc, # must be a list or tuple...comma makes this a 1-tuple. HPDF_New.argtypes = HPDF_Error_Handler, c_void_p
登錄后復(fù)制
請注意,參數(shù)類型必須基于 ctypes
類型。您必須仔細跟蹤參數(shù)并為每個函數(shù)聲明 .argtypes
。