VS調試其他程序(如pycharm等)調用的動態鏈接庫(dll):附加到進程(Attach to Process)

前言

Python與C語言聯合編程時,使用python調用dll庫是很常見的情況,因爲可以通過將常用函數或複雜函數封裝成C語言提高效率,但如何調試是一個問題。

正文

1.編寫dll文件

新建VS項目,選擇“Win32控制檯應用程序”或“Win32項目”(甚至“空項目”)都可以,在嚮導中選擇“DLL”。我個人是勾選“空項目”以及關閉“安全開發生命週期(SDL)檢查”,減少不必要的麻煩。

#define EXPORT __declspec(dllexport)

在一開始可以會加這樣一個宏定義來方便以後的書寫,這樣在需要外部調用的函數前加EXPORT即可。

2.編譯一次dll文件

與普通程序編譯步驟相似,生成解決方案即可。

只有生成dll文件之後,其他程序如pycharm才能調用這個文件,才能開始調試過程,因此需要先編譯一次,在Debug或Release目錄下得到dll文件,同時還有pdb文件等(若是x64平臺編譯,則還有一個x64上級目錄)。

注:根據需要應更改vs編譯平臺配置或更換python版本,因爲64位python無法直接調用32位dll,32位python也無法直接調用64位dll,即vs編譯平臺版本應與python版本對應。在“配置管理器”中可以新建x64編譯平臺:

3.python腳本調用dll庫

python調用dll庫需要使用ctypes包,資料很豐富,可自行學習——>官方文檔,示例如下:

import numpy as np
import numpy.ctypeslib as npct
from ctypes import c_int


#定義float型連續指針的數據類型
p_float = npct.ndpointer(dtype=np.float32, ndim=1, flags='CONTIGUOUS')
#導入dll庫,注意這裏的路徑是第一次編譯的文件位置
libcd = npct.load_library("D:\\Document\\VS\\dll_demo\\x64\\Debug\\test", ".")
#定義返回值類型
libcd.test.restype = None
#定義參數類型
libcd.test.argtypes = [p_float, c_int, c_int, c_int]
#調用函數
libcd.test(a,b,c,d)

 若只在pycharm內進行調試,在進行到最後的調用步驟時,調試器無法進入C代碼中,會很不方便,尤其是帶有指針的參數傳遞時,往往只會得到一個出錯的內存位置,並不知道發生了什麼問題。

4.聯合調試

先在pycharm內調用dll庫函數之前設一個斷點,讓調試器停到這個位置。

然後打開dll文件所在的VS項目,在dll庫的代碼中設斷點。 

選擇VS上面選項中的“調試(Debug)”——>“附加到進程(Attach to Process)”,選擇進程進行附加(Attach)

注意使用pycharm調試腳本時,應附加的進程是python而不是pycharm,同理以其他方式調試時(如參考資料中的cmd)也應選擇附加到python進程。

在pycharm中繼續運行,即可運行到C程序中的斷點處,就可以和普通C程序一樣調試了。

這種方法具有很強的普遍性,不得不說VS真的很強。

 

參考資料

StackOverflow大佬的精闢總結

另一種從配置VS調試器的角度得到的方法,兩種方法本質是一樣的

對我的啓發文章和一些可補充內容

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章