C/C++與Python實現混編(詳細注釋)


github博客傳送門
csdn博客傳送門

網上找了好多教程都是轉載的同一個人的,並且沒有講清楚 嵌入的關鍵步驟,整理后今天先來點簡單的.

主講 c/c++ 編譯為 .so 文件 嵌入 Python 實現混編

目錄:

  1. C語言版 hello
  2. C++語言版 hello
  3. C語言版加法器 有參無返回值
  4. C語言版加法器 有參有返回值
  5. C++語言版加法器 有參無返回值
  6. C++語言版加法器 有參有返回值
  7. C++語言Class版

環境

  1. Python執行環境 (隨便安裝個Python版本添加 path就可以使用)
  2. c/c++ 執行環境 (我安裝的是Dev-C++開發者工具 因為它小, 然后將 dev安裝目錄下的bin文件夾的路徑添加到path環境變量即可在命令提示符使用)

如果有嘗試失敗的可以下載我編譯好的 .so 文件嘗試使用

下載鏈接:https://download.csdn.net/download/zhanghao3389/10723128
文件目錄
所有文件夾

命令解釋:
gcc c語言編譯命令
g++ c++語言編譯命令
參數 -o hello.so 輸出 hello.so文件
參數 -shared 共享的
參數 -fPIC 告訴編繹器使用GOT和PLT的方法重定位
最后 跟上自己寫的 文件名
例: gcc -o hello_c.so -shared -fPIC hello_c.c // 將 hello_c.c 編譯生成了 hello_c.so 文件在當前目錄下



每個代碼第一行注釋是當前文件名

C語言版 hello

// hello_c.c
#include<stdio.h>
#include<stdlib.h>
void hello()                       // 定義一個 hello的方法
{
    printf("hello python and c");  // 輸出一段字符串
}

打開命令提示符進入當前文件夾輸入命令
gcc -o hello_c.so -shared -fPIC hello_c.c
當前文件夾下生成一個 hello_c.so 文件
編寫Python版調用程序
並執行Python程序

# hello_c.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("./hello_c.so")     # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
func.hello()                  # 調用 func中的hello方法


C++語言版 hello

// hello_c++.cpp
#include<iostream>
using namespace std;  // 命名空間

           // 比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。
           // 這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規范來鏈接。
extern "C" // extern修飾符可用於指示C或者C++函數的調用規范。
{
    void hello()                                  // 定義一個hello方法
    {
        cout << "hello python I'm cout" << endl;  // 輸出一段字符串
        printf("hello python I'm printf");        // 輸出一段字符串
    }
}

打開命令提示符進入當前文件夾輸入命令
g++ -o hello_c++.so -shared -fPIC hello_c++.cpp
當前文件夾下生成一個 hello_c++.so 文件
編寫Python版調用程序
並執行Python程序

# hello_c++.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("./hello_c++.so")   # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
func.hello()                  # 調用 func中的hello方法


C語言版加法器 有參無返回值

// add_c_1.c
#include <stdio.h>  
#include <stdlib.h>  
int add(int a, int b)  // 定義一個 add方法 返回值為 int 傳入兩個參數 a,b 類型為 int
{
    int result;                             // 定義一個 int 類型的 result變量
    printf("you input %d and %d\n", a, b);  // 輸出傳入的兩個參數
    result = a + b;                         // 計算兩個參數相加的結果賦給 result
    printf("result is: %d", result);        // 輸出計算結果后的值
}

打開命令提示符進入當前文件夾輸入命令
gcc -o add_c_1.so -shared -fPIC add_c_1.c
當前文件夾下生成一個 add_c_1.so 文件
編寫Python版調用程序
並執行Python程序

# add_c_1.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("./add_c_1.so")     # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
func.add(6, 8)                # 調用 func中的add方法 並傳值 6, 8 給它


C語言版加法器 有參有返回值

// add_c_2.c
#include <stdio.h>  
#include <stdlib.h>  
int add(int a, int b)                       // 定義一個 add方法 返回值為 int 傳入兩個參數 a,b 類型為 int
{
    printf("you input %d and %d\n", a, b);  // 輸出傳入的兩個參數
    return a+b;                             // 返回計算后的值
}

打開命令提示符進入當前文件夾輸入命令
gcc -o add_c_2.so -shared -fPIC add_c_2.c
當前文件夾下生成一個 add_c_2.so 文件
編寫Python版調用程序
並執行Python程序

# add_c_2.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("./add_c_2.so")     # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
print(func.add(6, 8))         # 調用 func中的add方法 並傳值 6, 8 給它


C++語言版加法器 有參無返回值

// add_c++_1.cpp
#include<iostream>
using namespace std;  // 命名空間
           // 比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。
           // 這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規范來鏈接。
extern "C" // extern修飾符可用於指示C或者C++函數的調用規范。
{
    int add(int a, int b)  // 定義一個 add方法 返回值為 int 傳入兩個參數 a,b 類型為 int
    {
        int result;                                                // 定義一個 int 類型的 result變量
        cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 輸出傳入的兩個參數
        printf("you input %d and %d, I'm printf.\n", a, b);        // 輸出傳入的兩個參數
        result = a + b;                                            // 計算兩個參數相加的結果賦給 result
        cout << "result is: " << result << ", I'm cout." << endl;  // 輸出計算結果后的值
        printf("result is: %d, I'm printf.\n", result);            // 輸出計算結果后的值
    }
}

g++ -o add_c++_1.so -shared -fPIC add_c++_1.cpp
當前文件夾下生成一個 add_c++_1.so 文件

# add_c++_1.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("add_c++_1.so")     # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
func.add(66, 88)              # 調用 func中的add方法 並傳值 66, 88 給它


C++語言版加法器 有參有返回值

// add_c++_2.cpp
#include<iostream>
using namespace std;  // 命名空間
           // 比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。
           // 這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規范來鏈接。
extern "C" // extern修飾符可用於指示C或者C++函數的調用規范。
{
    int add(int a, int b)  // 定義一個 add方法 返回值為 int 傳入兩個參數 a,b 類型為 int
    {
        cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 輸出傳入的兩個參數
        printf("you input %d and %d, I'm printf.\n", a, b);                  // 輸出傳入的兩個參數
        return a+b;                                                          // 返回a+b后的值
    }
}

g++ -o add_c++_2.so -shared -fPIC add_c++_2.cpp
當前文件夾下生成一個 add_c++_2.so 文件

# add_c++_2.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("add_c++_2.so")     # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
print(func.add(66, 88))       # 調用 func中的add方法 並傳值 66, 88 給它


C++語言Class版

// c++class.cpp
#include <iostream>  
using namespace std;                            // 命名空間
  
class HelloAndAdd                               // 定義一個 hello的方法 和一個 add的方法
{
    public:  
        void hello();                           // 定義一個hello的方法 無參無返回值
        void add(int a, int b);                 // 定義一個 add 方法 傳入兩個值 進行加法運算
};  
void HelloAndAdd::hello()                       // 定義HelloAndAdd里 hello方法的主體
{
    cout<<"Hello C++ class , I'm cout."<<endl;  // 輸出
    printf("Hello C++ class , I'm printf.");    // 輸出
}
  
void HelloAndAdd::add(int a, int b)                            // 定義HelloAndAdd里 add 方法的主體
{
    int result;                                                // 定義一個result 接收傳入兩個參數的結果
    cout << "you input " << a << " and " << b << ", I'm cout." << endl;  // 輸出傳入的兩個參數
    printf("you input %d and %d, I'm printf.\n", a, b);        // 輸出傳入的兩個參數
    result = a+b;                                              // 計算兩個參數相加的結果賦給 result
    cout << "result is: " << result << ", I'm cout." << endl;  // 輸出計算結果后的值
    printf("result is: %d, I'm printf.\n", result);            // 輸出計算結果后的值
    
}

           // 比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。
           // 這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規范來鏈接。
extern "C" // extern修飾符可用於指示C或者C++函數的調用規范。
{
    HelloAndAdd haa;           // 實例化HelloAndAdd對象為 haa
    void hello()               // 定義Python訪問該方法的 方法名
    {
        haa.hello();           // 傳入上述方法執行的主體 等價於 return haa.hello();
    }
    void add(int a, int b)     // 定義Python訪問該方法的 方法名 並傳入參數
    {
        return haa.add(a, b);  // 傳入上述方法執行的主體 並傳入參數
    }
}

g++ -o c++class.so -shared -fPIC c++class.cpp
當前文件夾下生成一個 c++class.so 文件

# c++class.py
import ctypes                 # 導入ctypes包
so = ctypes.cdll.LoadLibrary  # 將包中的LoadLibrary方法賦給 so
func = so("./c++class.so")    # 用 LoadLibrary 方法 打開當前文件夾下的 打包為 .so 格式的文件 並賦給func
func.hello()                  # 調用 func中的hello方法
print('\n----------')
func.add(10, 20)              # 調用 func中的add方法 並傳入參數 10, 20

編寫不易,求助攻一個...

print_r('點個贊吧');
var_dump('點個贊吧');
NSLog(@"點個贊吧!")
System.out.println("點個贊吧!");
console.log("點個贊吧!");
print("點個贊吧!");
printf("點個贊吧!\n");
cout << "點個贊吧!" << endl;
Console.WriteLine("點個贊吧!");
fmt.Println("點個贊吧!")
Response.Write("點個贊吧");
alert(’點個贊吧’)


免責聲明!

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



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