ubuntu下將c++轉換為so文件並利用python調用


ubuntu下將c++轉換為so文件並利用python調用

#轉載自:https://www.it610.com/article/1295144844422881280.htm

python調用.so

LINUX下C++生成.so文件及編譯生成可執行文件的過程

[linux][原創]C++ so庫的編譯python調用

python 打包成 so | python 調用cpp | python 調用C++簡單例子

C++轉so文件

這里以簡單的加法為例,代碼如下,add傳入兩個int的參數,完成加法。主函數main調用add,return結果。這里需要注意的點在於,不能忘記將函數添加到extern C中。原因是python 的ctype可以調用C而無法調用c++,加上extern "C"后,會指示編譯器這部分代碼按C語言(而不是C++)的方式進行編譯。

#include 
using namespace std;

extern "C"{

   double add(int, int);

}
double add(int x1, int x2)
{
    return x1+x2;
}
int main()
{
  int a = 1;
  int b =2 ;
  int c;
  c = add(a,b);
  return c;
}

之后打開窗口,輸入以下命令,即將上述cpp文件轉換為了so文件,注意so文件的名稱必須以lib開頭。

g++ add.cpp -fpic -shared -o libadd.so

python調用so文件

import ctypes  
ll = ctypes.cdll.LoadLibrary   

lib = ll("./libadd.so") 
input1 = 100
input2 = 220
result1 = lib.add(input1,input2)
result2 = lib.main()
print(result1,result2)
print '***finish***' 

python調用.so多個C++文件轉so文件可以看到最后結果為(320,3)

如果c++中add函數的輸入為double,則python調用so文件時需要將輸入input1 input2,以及add的輸出都轉換為double的形式,代碼如下:

lib.add.restype = ctypes.c_double
result1 = lib.add(ctypes.c_double(input1),ctypes.c_double(input2))

多個C++文件轉so文件

下面將多個cpp文件轉換為so文件,下面是一個例子:

其中convert.cpp是需要調用的函數,如下,主要的兩個函數是xy2lalong和laton2xy,兩個函數的返回都是double型的數組。

#include 
#include 
#include "AffineModel.h"
#include "RPCGeoModel.h"

extern "C"{
    double * xy2lalong(double, double, char*);
    double * latlon2xy(double, double, char*);
}

double * xy2lalong(double x, double y,char* rpcpath)
{
    string m_prpc=rpcpath;
    //printf("%s\n",m_prpc);
    CRPCGeoModel m_prpc1;
    m_prpc1.InitRPCModel(m_prpc);
    double *latlon =new double[2];
    m_prpc1.GetLatLonByAffine(x,y, 0,latlon[0], latlon[1]); //像素坐標轉經緯度
    //printf("you input %f and %f\n", latlon[0], latlon[1]);
    return latlon;
}

double * latlon2xy(double lat ,double lon,char* rpcpath)
{
    string m_prpc=rpcpath;
    //printf("%s\n",m_prpc);
    CRPCGeoModel m_prpc1;
    m_prpc1.InitRPCModel(m_prpc);
    double *xy =new double[2];
    m_prpc1.GetXY(lat, lon, 0, xy[0], xy[1]); //經緯度轉像素坐標
    return xy;
}

對於多個cpp轉程so文件,命令如下:

g++ -std=gnu++0x convert.cpp AffineModel.cpp CommonFunc.cpp RPCGeoModel.cpp -fPIC -shared -o libconvert.so

即將cpp文件名稱都輸入至終端,然后加上-fPIC -shared -o 表示生成共享庫,最后加上 libXXX.so。注意一定要加上-std=gnu++0x,否則會出現如下錯誤。

error: ‘nullptr’ was not declared in this scope
  FILE *fp= nullptr;

之后用python調用,如下。由於c++中函數的輸出是一個double的數組,那么在python的調用中也需要將函數的輸出轉換為相同的類型(lib.function.restype = ctypes.POINTER(ctypes.c_double)),即double的數組。

input1 = 100.0
input2 = 100.0
lib.xy2lalong.restype = ctypes.POINTER(ctypes.c_double)
a = lib.xy2lalong(ctypes.c_double(input1),ctypes.c_double(input2), strs)
print(a[0],a[1])

input1 = 9.1949132495
input2 = 118.038103295
lib.latlon2xy.restype = ctypes.POINTER(ctypes.c_double)
b = lib.latlon2xy(ctypes.c_double(input1),ctypes.c_double(input2),strs)
print(b[0],b[1])
print '***finish***' 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM