# 0x0 start
首先导入 Python.h, 并添加 python37_d.lib 依赖
# 0x1 遇到的问题
刚开始跟着教程走,结果总是提示缺少 python37_d.lib 依赖,后来根据下面的找到的教程才发现库目录才是有依赖搜索的目录
~~ 看教程里是从上往下数第四个改成了 C:\environment\Python37\libs 结果被骗了…~~QAQ
https://blog.csdn.net/bandaoyu/article/details/105102945
于是 vs 的 VC++ 目录的配置可以如图所示
并且在链接器的输入子目录内添加 python python37_d.lib
依赖
这样修改 Python.h 头文件可以正确的包含进来
# 0x2 试用网上的 c 调用 python 的代码
#include<stdio.h> | |
#include <Python.h> | |
int main() | |
{ | |
PyObject *pName, *pModule, *pDict, *pFunc; | |
PyObject *pArgs, *pValue; | |
// 待传参数 | |
int time[6]={1,2,3,4,5,6}; | |
// 初始化 python | |
Py_Initialize(); | |
// 检查初始化是否成功 | |
if (!Py_IsInitialized()) | |
{ | |
printf("初始化失败\n"); | |
Py_Finalize(); | |
} | |
// 设置 python 模块,搜寻位置,文件放在.c 文件一起 | |
PyRun_SimpleString("import sys"); | |
PyRun_SimpleString("sys.path.append('./')"); | |
// 获取 python 文件名,导入模块(我这里的 py 文件是 graph.py) | |
pModule = PyImport_ImportModule("graph"); | |
if (!pModule) { | |
printf("py文件导入失败\n"); | |
Py_Finalize(); | |
} | |
else { | |
// 直接获取模块中的函数 | |
pFunc = PyObject_GetAttrString(pModule, "create_graph"); | |
// 验证函数是否获取成功 | |
if (!pFunc) { | |
printf("函数导入失败\n"); | |
Py_Finalize(); | |
} | |
// 将 c/c++ 类型数据转换为 python 类型,利用元组传递 | |
pArgs = PyTuple_New(6); | |
pValue = PyLong_FromLong(time[0]); | |
PyTuple_SetItem(pArgs, 0, pValue); | |
pValue = PyLong_FromLong(time[1]); | |
PyTuple_SetItem(pArgs, 1, pValue); | |
pValue = PyLong_FromLong(time[2]); | |
PyTuple_SetItem(pArgs, 2, pValue); | |
pValue = PyLong_FromLong(time[3]); | |
PyTuple_SetItem(pArgs, 3, pValue); | |
pValue = PyLong_FromLong(time[4]); | |
PyTuple_SetItem(pArgs, 4, pValue); | |
pValue = PyLong_FromLong(time[5]); | |
PyTuple_SetItem(pArgs, 5, pValue); | |
// 调用直接获得的函数,并传递参数 | |
pValue = PyObject_CallObject(pFunc, pArgs); | |
// 释放 python | |
Py_Finalize(); | |
printf("success"); | |
return 0; | |
} | |
} |
graph.py 的代码
# -*- coding:utf-8 -*- | |
import xlsxwriter | |
def create_graph(a,b,c,d,e,f): | |
# 创建一个 excel | |
workbook = xlsxwriter.Workbook("排序算法比较结果.xlsx") | |
# 创建一个 sheet | |
worksheet = workbook.add_worksheet() | |
# worksheet = workbook.add_worksheet("bug_analysis") | |
# 自定义样式,加粗 | |
bold = workbook.add_format({'bold': 1}) | |
# --------1、准备数据并写入 excel--------------- | |
# 向 excel 中写入数据,建立图标时要用到 | |
headings = ["排序方法", "排序时间"] | |
data = [["简单选择排序", "直接插入排序", "冒泡排序", "快速排序", "两路合并排序", "堆排序"],[a,b,c,d,e,f]] | |
# 写入表头 | |
worksheet.write_row('A1', headings, bold) | |
# 写入数据 | |
worksheet.write_column('A2', data[0]) | |
worksheet.write_column('B2', data[1]) | |
# --------2、生成图表并插入到 excel--------------- | |
# 创建一个柱状图 (column chart) | |
chart_col = workbook.add_chart({'type': 'column'}) | |
# 配置第一个系列数据 | |
chart_col.add_series({'name': '=Sheet1!$B$1','categories': '=Sheet1!$A$2:$A$7','values': '=Sheet1!$B$2:$B$7','line': {'color': 'red'},}) | |
# 这里的 sheet1 是默认的值,因为我们在新建 sheet 时没有指定 sheet 名 | |
# 如果我们新建 sheet 时设置了 sheet 名,这里就要设置成相应的值 | |
# 设置图表的 title 和 x,y 轴信息 | |
chart_col.set_title({'name': "排序算法结果"}) | |
chart_col.set_x_axis({'name': "排序方法"}) | |
chart_col.set_y_axis({'name': "花费时间(ms)"}) | |
# 设置图表的风格 | |
chart_col.set_style(1) | |
# 把图表插入到 worksheet 以及偏移 | |
worksheet.insert_chart('A10', chart_col, {'x_offset': 25, 'y_offset': 10}) | |
workbook.close() | |
return 0 | |
if __name__=="__main__": | |
create_graph(10, 40, 50, 20, 10, 50) |
芜湖运行成功!
没想到第一次运行就如此顺利
在看看源文件下的目录有没有生成 .xlsx
文件
确实多了一个,不错不错.
# 0x3 自己写一个 helloworld!
不过这个 helloworld 是调用 python 的函数打印的
可恶新开了一个解决方案,又得重新配置包含目录了, 心累
#include<Python.h> | |
#include<stdio.h> | |
int main() | |
{ | |
PyObject* pName, * pModule, * pDict, * pFunc; | |
PyObject* pArgs, * pValue;// 经典复制粘贴变量(这玩意儿自己一个一个打也太麻烦了而且也记不住呀) | |
Py_Initialize();// 初始化一下~ | |
if (!Py_IsInitialized())// 看看初始化有没有成功 | |
{ | |
printf("初始化失败\n"); | |
Py_Finalize(); | |
} | |
PyRun_SimpleString("import sys");// 设置 python 模块,搜寻位置,文件放在.c 文件一起 | |
PyRun_SimpleString("sys.path.append(./)"); | |
pModule = PyImport_ImportModule("hello");// 导入 hello.py | |
if (!pModule) | |
{ | |
printf("py文件导入失败\n"); | |
Py_Finalize(); | |
} | |
else//hello.py 如果打开成功,直接获取模块的函数 | |
{ | |
pFunc = PyObject_GetAttrString(pModule, "printhello"); | |
if (!pFunc) { | |
printf("函数导入失败\n"); | |
Py_Finalize(); | |
} | |
} | |
// 没参数,就不用 demo0 里面那么麻烦啊吧啊吧了~ | |
pValue = PyObject_CallObject(pFunc, pArgs);// 调用函数 | |
Py_Finalize();// 释放 python | |
return 0; | |
} |
def printhello() | |
print("hello,world!") | |
printhello() |
写好啦~运行看看
pFunc
可能未初始化都不让运行,真 gou!
#include<Python.h> | |
#include<stdio.h> | |
int main() | |
{ | |
PyObject* pName, * pModule, * pDict, * pFunc; | |
PyObject* pArgs,* pValue;// 经典复制粘贴变量(这玩意儿自己一个一个打也太麻烦了而且也记不住呀) | |
Py_Initialize();// 初始化一下~ | |
if (!Py_IsInitialized())// 看看初始化有没有成功 | |
{ | |
printf("初始化失败\n"); | |
Py_Finalize(); | |
} | |
PyRun_SimpleString("import sys");// 设置 python 模块,搜寻位置,文件放在.c 文件一起 | |
PyRun_SimpleString("sys.path.append('./')"); | |
pModule = PyImport_ImportModule("hello");// 导入 hello.py | |
if (!pModule) | |
{ | |
printf("py文件导入失败\n"); | |
Py_Finalize(); | |
return 1; | |
} | |
pFunc = PyObject_GetAttrString(pModule, "printhello"); | |
if (!pFunc) { | |
printf("函数导入失败\n"); | |
Py_Finalize(); | |
} | |
pArgs = NULL; | |
pValue = PyObject_CallObject(pFunc, pArgs);// 调用函数 | |
Py_Finalize();// 释放 python | |
return 0; | |
} |
代码改好可以运行咯
为啥这个 hello,world!
输出两次嘞
看来 c 调用 python 也是先把 main 函数运行一遍的哈
# 0x4 接下来,开始逆向的工作~
单独运行一下 can can
晕!还得 py 文件才能让你老老实实运行吗!?
把 hello.py
拖进去一份,, 正常运行
IDA 进去看看
# 参考资料
- https://www.jb51.net/article/212125.htm