c调用python第三方库_用 Python ctypes 来调用 C/C++ 编写的第三方库
看到一篇簡潔的文章--如何用Python ctypes調(diào)用C++(ctypes調(diào)用C沒這么多麻煩事),不敢獨享...
如果需要用 Python 調(diào)用 C/C++ 編寫的第三方庫(這些第三方庫很可能就是你之前寫出來的),只是需要一個腳本語言來粘合它們。這個時候,用Python ctypes可以很方便地實現(xiàn)調(diào)用。
StackOverflow 上的 Calling C/C++ from python 這個主題介紹了 ctypes 最簡單的入門方法,概括如下:
如果是 C 函數(shù)庫,則直接 load 這個庫,然后調(diào)用即可;
如果是 C++ 函數(shù)庫,則需要用 extern 關(guān)鍵字封裝一個供 C 使用的函數(shù),即把類隱藏到一些 C 風格的函數(shù)里,然后用 extern 標明這些函數(shù),以方便外部調(diào)用。
這兩種方法里,弄懂了 ctypes 調(diào)用 C++ 庫的方法,就會用 ctypes 調(diào)用 C 函數(shù)庫,對 C++ 庫的基本方法如下。
例如,有一個 C++ 類 Foo:
#include class Foo{ public: void bar(){ std::cout << "Hello" << std::endl;
}
};
再封裝出下面 C 風格的接口函數(shù):
extern "C" { Foo* Foo_new(){ return new Foo();
} void Foo_bar(Foo* foo){
foo->bar();
}
}
把上面的代碼編譯成動態(tài)鏈接庫:
g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
,然后再用 Python 寫的代碼來調(diào)用這個類,你可以把上面兩個 C 接口函數(shù)寫成 Python 類,或是直接調(diào)用:
from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')
class Foo(object):
def __init__(self):
self.obj = lib.Foo_new()
def bar(self):
lib.Foo_bar(self.obj)
,然后就可以在 Python 腳本里調(diào)用這個 Python 類了:
f = Foo()
f.bar() #and you will see "Hello" on the screen
在 Windows 下用 Python ctypes 的方法和上面一樣,只是有下面兩點需要注意一下:
在編寫 Python 代碼時,剛開始鏈接所需的動態(tài)鏈接庫時,最好使用絕對路徑來 load,以減少出錯概率,加快調(diào)試速度
在我按上面的方法編寫好了上述代碼時,一運行腳本,則提示如下錯誤信息: $ python Linkcpp.py
Traceback (most recent call last):
File "Linkcpp.py", line 2, in
lib = cdll.LoadLibrary('./LinkExample')
File "C:\Python27\lib\ctypes\__init__.py", line 431, in LoadLibrary
return self._dlltype(name)
File "C:\Python27\lib\ctypes\__init__.py", line 353, in __init__
self._handle = _dlopen(self._name, mode)
WindowsError: [Error 126]
這是因為我在代碼里是使用了這樣的代碼來導入動態(tài)鏈接庫: from ctypes import cdll
lib = cdll.LoadLibrary('./LinkExample')
如果把 ./LinkExample 這句換成 Windows 下的絕對路徑 E:/PythonCode/LinkCpp/LinkExample,則沒有錯誤提示了。當然,你直接把 ./LinkExample 換成 LinkExample 也可以找到該鏈接庫。
所以,剛開始的時候,使用絕對路徑,以確保你不會糾結(jié)于能不能找到鏈接庫之類的問題。
在運行上述腳本的時候,出現(xiàn) WindowsError: [Error 126] 的錯誤,無非就是兩個原因:
你的 DLL 沒有正確地被加載;
你的 DLL 依賴的其它 DLL 沒有被找到或是加載失敗。
另外,注意一下,Windows 下因為庫分為 lib 和 dll 兩個文件,所以可以只輸入庫的名稱即可,比如說你要鏈接 LinkExample.dll 庫,則可以在 ctypes 里只需要聲明鏈接名為 LinkExample 庫即可。
如果是 C++ 寫的庫,需要用上 extern 關(guān)鍵字,這個和一般的供 C 調(diào)用的 C++ 庫頭文件是一樣的
在 extern 聲明的函數(shù)里,可以使用 C++ 里 C 沒有的關(guān)鍵字,比如我的函數(shù)就是這樣聲明的: extern int linkExample(const int index, const char* name);
上面代碼可以從 Python 調(diào)用運行。
extern 這個關(guān)鍵字在 C++ 里的用法比較復(fù)雜,在這里就是要聲明一個供 C 使用的外部函數(shù),而這個函數(shù)本身,卻可以使用 C++ 的語法,包括 const 關(guān)鍵字等。
Copyright ? 2013, 瀏忙大爆炸. All rights reserved.
除非注明,瀏忙大爆炸文章均為原創(chuàng),轉(zhuǎn)載請以鏈接形式標明本文地址。
總結(jié)
以上是生活随笔為你收集整理的c调用python第三方库_用 Python ctypes 来调用 C/C++ 编写的第三方库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 要发力了?vivo重磅折叠屏手机曝光 轻
- 下一篇: python怎么用for循环找出最大值_