網上找了好多教程都是轉載的同一個人的,並且沒有講清楚 嵌入的關鍵步驟,整理后今天先來點簡單的.
主講 c/c++ 編譯為 .so 文件 嵌入 Python 實現混編
目錄:
- C語言版 hello
- C++語言版 hello
- C語言版加法器 有參無返回值
- C語言版加法器 有參有返回值
- C++語言版加法器 有參無返回值
- C++語言版加法器 有參有返回值
- C++語言Class版
環境
- Python執行環境 (隨便安裝個Python版本添加 path就可以使用)
- 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(’點個贊吧’)