持续记录Python与c++相互调用的各类方式和遇到的问题

1.python调用c++:

1.1 第一种调用方式:直接调用C++编译生成的exe文件

Python代码:

import os

cpptest = r".\cpp.exe"                                      # exe路径,linux中不加后缀exe
os.system(cpptest + ' ' + path)                             # 中文使用GBK编码

C++代码:

void main(int argc, char* argv[])
{
    //输出传进来的参数及个数
	cout << "argc:"<< argc << endl;
	cout << "argv:"<< argv[0] << endl;              
	return;
}

调用非常简单,但是要注意以下问题:
a. os.system(cpptest + ' ' + path) 这句话就是调用cpptest路径中的exe文件并传参,这里我传递的是一个含有中文的路径path,实测要将python的File Encoding改为GBK或者GB2312,按理说使用默认的UTF-8是可以传递中文的,这里没太搞懂;
b. 括号中的每一项都要用空格(' ')分开,再用加号连接;
c. 这种传参方式其实就是给C++的主函数传参,所以C++中必须有带参数的main函数
d. 生成的exe复制到别的位置再调用时会报各种缺库的错,只要把报错的库一起复制过来即可,好像是有可以不用复制的方法,后面用到了再更新;

此方法优点:传参方便,无多余操作
缺点:单独运行exe时可以在C++中用下面的命令禁止黑窗口,但是python调用时始终弹出黑窗口,目前没找到有效的去除方法

#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )

或者

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

1.2 第二种调用方式:调用c++生成的dll动态链接库

如何用VS生成dll文件就不多说了,需要注意的就是32为或64位的选择,要与python对应。

Python代码:

   import ctypes
   
   strTest = bytes(path, encoding='gbk')                            #path为含有中文的路径名,要以比特形式传递,使用GBK或GB2312编码
   LoadCpp = ctypes.cdll.LoadLibrary("./data/Win32DLL.dll")         #载入dll
   print(LoadCpp.add(1,2,strTest)                                  #调用add函数

C++代码:

extern "C" __declspec(dllimport) int add(int a, int b,char * path);//声明需要调用的函数
    
int add(int a, int b,char * path)
{
    int c = a + b;
    string strPath = path;                                          //char* 转为字符串
    cout<<strPath<<endl;
  	return c;
}

这种调用方式不需要有main函数,也不会有黑窗口,但不知道可移植性怎么样,后续跟进

其他类型参数的传递:
https://blog.csdn.net/MrCheny/article/details/79022973

2.C++调用python:

C++代码:

#include <Python.h>
#include<iostream>
using namespace std;

//调用python函数
Py_SetPythonHome(L"C:\\Users\\Programs\\Python\\Python37");//导入python环境
Py_Initialize();                                                                 //使用python之前,要调用Py_Initialize();这个函数进行初始化
if (!Py_IsInitialized())
{
	printf("初始化失败!");
	return;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('H:\\pythontest')");    //修改需要调用的Python文件路径
//加载文件
PyObject* pModule = PyImport_ImportModule("cpp_py");                             //需要调用的py文件名,不包括后缀
if (pModule == NULL)
{
	cout << "没找到python文件" << endl;
}
//选中调用函数,返回函数指针
PyObject* pFunSetSeedPoint = PyObject_GetAttrString(pModule, "pytest");
// 输入的参数 
PyObject* args = PyTuple_New(2);
PyObject* pReturnValue;

//设置参数
string OriginBmpPath = "D:/test2/bmpmask";
string OriginDcmPath = "D:/test2/dcmorigin";

cout << OriginBmpPath << endl;

PyTuple_SetItem(args, 0, Py_BuildValue("s", "D:\\test2\\dcmorigin"));           //参数表
PyTuple_SetItem(args, 1, Py_BuildValue("s", "D:\\test2\\bmpmask"));

//PyTuple_SetItem(args, 0, Py_BuildValue("s", OriginDcmPath));                  //以变量的形式传递字符串会报错
//PyTuple_SetItem(args, 1, Py_BuildValue("s", OriginBmpPath));

//调用函数
pReturnValue = PyObject_CallObject(pFunSetSeedPoint, args);

//转换返回值
int ret = 0;
PyArg_Parse(pReturnValue, "i", &ret);                                          //转换返回类型
cout << "ret:" << ret << endl;                                                 //输出结果

Py_Finalize();

Python代码:

def pytest(path0,path1):
    print(path0)
    print(path1)
    return 100
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值