网上找了好多教程都是转载的同一个人的,并且没有讲清楚 嵌入的关键步骤,整理后今天先来点简单的.
主讲 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 文件尝试使用
下载链接:
命令解释:
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(’点个赞吧’)