1. 程式人生 > >Python呼叫C/C++動態庫

Python呼叫C/C++動態庫

兩種方案

1.利用ctypes.cdll.LoadLibrary直接在python中呼叫

C++動態庫中函式的定義,關於動態庫的生成請參考GCC生成及呼叫動態庫和靜態庫

extern "C"{
 string c_r(){
 	return "test0\n";
 }
 char* c_t(){
 	return "test1\n";
 }
 }
 

python中呼叫

import ctypes
dl=ctypes.cdll.LoadLibrary
lib=dl("./libreply.so")

因為型別轉換問題,如果呼叫c_r(),會直接崩潰

>>> reply=lib.c_r
>>> reply()
[1]    2618 segmentation fault (core dumped)  python

如果要呼叫c_t(),需要先設定函式的返回值型別

>>> reply=lib.c_t
>>> reply.restype=ctypes.c_char_p
>>> reply()
'test1\n'
>>> print(reply())
test1

但是如果中文的話還需要再解碼,新定義一個返回原值的函式

char* c_reply(char* inputStr){
	if(inputStr==NULL)
		return "需要輸入\n";
	else
     	return (char*)string(inputStr).c_str();
    
 }
>>> print(reply("你好").decode("utf-8"))
你好

如果沒有解碼為utf-8的話不能正常顯示中文

2.在C++檔案中呼叫<Python.h>將要使用的函式和類等封裝為python物件,然後作為一個模組供python使用

C++檔案如下

#include<iostream>
#include<stdlib.h>

using namespace std;

void printHello(){
	cout<<"你好"<<endl;
}
int getInt(int i){
	return i;
}
char* getCharArr(char* s){
	return s;
}
string getStr(string s){
	return s;
}
#include "/usr/include/python2.7/Python.h"//Python.h的位置到裝python的地方找
static PyObject *  Ext_printHello(PyObject *self, PyObject *args)  
{  
    printHello();  
    return (PyObject*)Py_BuildValue("");  
}  
static PyObject *  Ext_getInt(PyObject *self, PyObject *args)  
{  
    int num;  
    if (!PyArg_ParseTuple(args, "i", &num))  
        return NULL;  
    return (PyObject*)Py_BuildValue("i", getInt(num));  
}  
static PyObject *  Ext_getCharArr(PyObject *self, PyObject *args)  
{  
    char* s;  
    if (!PyArg_ParseTuple(args, "s", &s))  
        return NULL;  
    return (PyObject*)Py_BuildValue("s", getCharArr(s));  
}  
static PyObject *  Ext_getStr(PyObject *self, PyObject *args)  
{  
    string s;  
    if (!PyArg_ParseTuple(args, "s", &s))  
        return NULL;  
    return (PyObject*)Py_BuildValue("s", getStr(s));  
} 
static PyMethodDef  ExtMethods[] =  
{  
    { "printHello", Ext_printHello, METH_VARARGS },  
    { "getInt", Ext_getInt, METH_VARARGS },  
    { "getCharArr", Ext_getCharArr, METH_VARARGS }, 
    { "getStr",Ext_getStr,METH_VARARGS}, 
    { NULL, NULL },  
};  
extern "C"{//extern "C"必須加,不然會找不到入口函式
void initExt()  
{  
    Py_InitModule("Ext", ExtMethods);  
} 
}

編譯為動態庫Ext.so

python中呼叫,漢字仍然需要解碼為utf-8

>>> import Ext
>>> Ext.printHello()
你好
>>> Ext.getInt(99)
99
>>> Ext.getCharArr("你好\n")
'\xe4\xbd\xa0\xe5\xa5\xbd\n'
>>> print(Ext.getCharArr("你好\n").decode("utf-8"))
你好

>>> 

&呼叫Ext.getStr()時還是崩潰,看樣子是不支援string型別,只能用c_str()轉化為字串數字再返回

>>> Ext.getStr("hello")
[1]    5347 segmentation fault (core dumped)  python

附錄:


相關推薦

python呼叫C語言動態

python完美相容C語言,有了ctypes 可以呼叫c相關程式碼  如果是c++程式碼   編譯的時候加上 extern "C" 就可以了 ,如果是一些複雜型別比如結構體,類,聯合一些 可以考慮用boost.python exp.c #include <stdio

Linux下C程式動態的生成和呼叫

Linux下C程式動態庫的生成和呼叫 文章目錄 Linux下C程式動態庫的生成和呼叫 1 動態庫的打包和呼叫 2 靜態庫打包和呼叫 3 常用命令 4 gcc 和 g++ 區別 5 編譯和連結的理解

C語言動態建立方法,以及和python混合程式設計

這篇小結是2016年暑假在新疆出差階段所寫,因為專案需要所以研究了一下。 如有錯誤,歡迎互相交流。 不同編譯器實現python呼叫C語言動態庫方法小結 Windows平臺下Visual Studio 2010編譯器建立動態庫,並呼叫 第一步:建立動態dll動態庫

Linux連結三(CC++之間動態的相互呼叫

http://www.cppblog.com/wolf/articles/74928.html http://www.cppblog.com/wolf/articles/77828.html http://www.jb51.net/article/34990.htm extern "C"的理解: 很多人認

Java調用c程序動態詳細案例

mic fan 調用 c程序 案例 href java pid blank 1n閡嚎o指N階墑06灰tjhttp://huiyi.docin.com/arg9509 N19u4wTfnd塵2http://shufang.docin.com/fbqja96992 84稭棧

C# 調用 C++/CLI (托管模式c++) 的動態(DLL)

C++/CLI C# Dll調用 1.創建C++/CLI的動態庫 添加類 右鍵生成後即可生成 CLI_Dll.dll2.創建C#窗口應用程序,引用CLI_Dll.dll,然後就可以像是調用C#生成的的dll調用CLI_Dll.dll。C# 調用 C++/CLI (托管模式c++) 的動態庫(D

C#+NPOI動態 對Word的簡單編輯

眾裡尋他千百度,終回首,就在燈火闌珊處。 在很多人部落格上看見基於NPOI動態庫對word進行讀寫,但是沒有自己想要的效果(很多部落格都是對word中的表格做操作,這很正常,NPOI的官方使用文件從頭到尾的都是在講對Excel的操作),於是乎自己摸索了一個。在這裡覺得最最最重要的東

C++載入動態的形式來實現封裝

目錄結構 └── test ├── CMakeLists.txt ├── base.h //設定介面 ├── drive.cpp //具體實現 └── main.cpp

C++編寫動態.so或者.dll的陷阱

一、介面不變就可以不需要重新編譯? 對於很多庫的實現者可能會有這樣的認識“介面不變就可以不需要重新編譯”,其實這句話是有前提的,前提是實現的動態庫有足夠的相容性和魯棒性。尤其是C++實現的動態庫,C++只對語言層規則做了規定,沒有二進位制級別的任何規定。 COM本質論裡面的

Unity3d 載入 C++/CLI (託管模式c++) 的動態(DLL)

由於最近開發遊戲尋路A*使用非常頻繁.所以是邏輯上的瓶頸. c#又比c++慢一倍.所以決定上c++.這樣算一種優化吧.哈哈. 關於vs上的vc++.分託管和非託管模式.  託管模式就是 C++/CLI 也就說可以c++使用.net庫. 和 CLR是一起的.  還有就是 非託

c動態

程式編譯一般需經預處理、編譯、彙編和連結幾個步驟。在應用中,有一些公共程式碼是需要反覆使用,就把這些程式碼編譯為“庫”檔案;在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中。這種庫稱為靜態庫,其特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是

c++檢視動態中函式地址

我們知道在生成動態庫時,如果使用.def檔案.那麼可以在.def中定義函式地址即例: add @1這種方式.但畢竟這是一種取巧的方式,如果你想獲得任何一個動態庫中函式地址,那麼我這邊可以提供兩個方法.(1)使用vs自帶的功能我用的是VS2005開啟工具選項,下面有Visual

VS中C++靜態/動態檔案的編譯除錯與使用

基礎知識:不同語言之間可以通過呼叫動態連結庫 (dll)來呼叫別人寫好的函式同一語言可以呼叫別人寫好的靜態(lib)庫靜態連結庫:是通過靜態聯編的,在連結時,link將自己的(.obj)二進位制檔案和別人的lib檔案一起共同生成.exe檔案。 靜態連結庫的缺點是: 1)比較

C++中動態(.dll)和靜態(.lib)

最近,做一些程式的封裝,就瞭解了C++中封裝動態庫(.dll)和靜態庫(.lib)的方法,以及兩種庫呼叫時異同,現在記錄下,後續有新的理解,會繼續更新; 動態庫(.dll):動態庫又稱動態連結庫英文為

Python 專案轉.so動態

最近, 作者遇到一個需求, 需要把Python的工程部署到別的叢集, 但是又要保證Python程式碼的安全性. 於是上網搜尋, 搜到幾個解決方案, 但是都不是符合需求. 綜合搜到的幾個解決方案, 最終作者採用了編譯成so動態庫的方式釋出. 首先說一下搜到到幾個解決方案, 以及它們的優缺點 編譯成p

c++ 呼叫Python指令碼或者動態——環境Ubuntu 16.04下用codeblocks

背景:因為使用的是python版本的程式,最終要整合到C++環境的架構中,也就是說架構是c++的,交付使用者為c++的介面,但是呼叫的是python的庫,因此需要學習在c++環境下呼叫python。因為對python不熟悉,可以說有點一抹黑,因此從簡到難逐步探索。首先在c++

ApolloStudio高手之路(8):用Python呼叫.Net(C#、VB.Net等)開發的動態連結(DLL檔案)實現相互協作

ApolloStudio是基於.Net與Python雙架構下的實現,這樣的架構體系使得其具有傳統定製軟體無法比擬的超強拓展性,在本文中我們將介紹這兩者是如何在ApolloStudio平臺上實現優勢互補的。由於在ApolloStudio中使用的更易學習的Python作為主導指令碼語言,這裡我們將介

Python呼叫C/C++動態

兩種方案1.利用ctypes.cdll.LoadLibrary直接在python中呼叫C++動態庫中函式的定義,關於動態庫的生成請參考GCC生成及呼叫動態庫和靜態庫extern "C"{ string c_r(){ return "test0\n"; } char*

1.Python呼叫C語言之如何呼叫動態連結

平時用C&C++和Python比較多,喜歡鼓搗點小玩意兒。之前在《數學之美》這本書裡面看見布隆過濾器這個東西,簡直是爬蟲利器!所以當時用C++寫了一個簡單的,後來封裝成了動態連結庫拿來給爬蟲用。所以就研究了一下怎麼用Ptython呼叫C語言,寫個博文記錄一下! Py

python呼叫C動態匯出函式的返回值為指標型別時,在64位python環境下被截斷解決方法

          class my_void_p(c_void_p):               pass                      def sslog_create_instance():               #直接指定 restype=c_void_p在64位上還是會發生地址截