栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用C ++项目(Visual Studio)中的参数调用Python函数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用C ++项目(Visual Studio)中的参数调用Python函数

我尝试使用给定的intel复制问题,但是这是不可能的,因此我创建了一个小示例(尽可能接近问题中所描述的内容)-也称为[SO]:如何创建最小的,可复制的示例(reprex(mcve))(应该包含在问题
BTW中

因此,我在这里说明的问题是:

  • C ++
    • 加载 Python 引擎
    • 加载一个 Python 模块
    • 从该模块加载一个函数,该函数:
    • 接收代表文件名的(字符串)参数
    • 读取文件内容(文本)并返回
    • 如果出现错误,只需返回文件名
    • 调用该函数
    • 获取函数调用结果

我正在使用(在 Win 10 x64(10.0.16299.125)上 ):

  • Python 3.5.4 x64
  • VStudio 2015社区版

该结构包括:

  • VStudio 项目/解决方案
    • 源文件( main00.cpp (从 main.cpp 重命名 ,但不想重新制作所有包含它的屏幕截图)) __
  • Python 模块( experiment_test.py
  • 测试文件( test_file.txt

main00.cpp

#include <string>#include <iostream>#if defined(_DEBUG)#  undef _DEBUG#  define _DEBUG_UNDEFINED#endif#include <Python.h>#if defined(_DEBUG_UNDEFINED)#  define _DEBUG#  undef _DEBUG_UNDEFINED#endif#define MOD_NAME "experiment_test"#define FUNC_NAME "function_name"#define TEST_FILE_NAME "test_dir\test_file.txt"using std::cout;using std::cin;using std::endl;using std::string;int cleanup(const string &text = string(), int exitCode = 1) {    Py_Finalize();    if (!text.empty())        cout << text << endl;    cout << "Press ENTER to return...n";    cin.get();    return exitCode;}int main() {    char c;    string fName = TEST_FILE_NAME, result;    PyObject *pName = NULL, *pModule = NULL, *pDict = NULL, *pFunc = NULL, *pArgs = NULL, *pValue = NULL, *pResult = NULL;    Py_Initialize();    pName = PyUnipre_FromString(MOD_NAME);    if (pName == NULL) {        return cleanup("PyUnipre_FromString returned NULL");    }    pModule = Pyimport_import(pName);    Py_DECREF(pName);    if (pModule == NULL) {        return cleanup(string("NULL module: '") + MOD_NAME + "'");    }    pDict = PyModule_GetDict(pModule);    if (pDict == NULL) {        return cleanup("NULL module dict");    }    pFunc = PyDict_GetItemString(pDict, FUNC_NAME);    if (pFunc == NULL) {        return cleanup(string("module '") + MOD_NAME + "' doesn't export func '" + FUNC_NAME + "'");    }    pArgs = PyTuple_New(1);    if (pArgs == NULL) {        return cleanup("NULL tuple returned");    }    pValue = PyUnipre_FromString(fName.c_str());    if (pValue == NULL) {        Py_DECREF(pArgs);        return cleanup("PyUnipre_FromString(2) returned NULL");    }    int setItemResult = PyTuple_SetItem(pArgs, 0, pValue);    if (setItemResult) {        Py_DECREF(pValue);        Py_DECREF(pArgs);        return cleanup("PyTuple_SetItem returned " + setItemResult);    }    pResult = PyObject_CallObject(pFunc, pArgs);    Py_DECREF(pArgs);    Py_DECREF(pValue);    if (pResult == NULL) {        return cleanup("PyObject_CallObject returned NULL");    } else {        int len = ((PyASCIIObject *)(pResult))->length;        char *res = PyUnipre_AsUTF8(pResult);        Py_DECREF(pResult);        if (res == NULL) { return cleanup("PyUnipre_AsUTF8 returned NULL");        } else { cout << string("C(++) - Python call: ") << MOD_NAME << "." << FUNC_NAME << "('" << fName << "') returned '" << res << "' (len: " << len << ")" << endl;        }    }    return cleanup("OK", 0);}

注意事项

  • 开头的 DEBUG_ / __DEBUG_UNDEFINED_ 内容-在 调试 模式下构建时(与 _python35 _ d* .lib_ 相对),一个( lam )解决方法( gainarie )链接到 Release Python lib( python35.lib )- __ _ *_

  • 如我所说,尝试简化代码(摆脱了 PyCallable_Check 测试)

  • 尽管代码使用 _ C ++*_ 编译器,但很容易注意到它是用 _ C_ 风格编写的 _ *_

  • 由于 Python的API ([Python.Docs]:Python嵌入在另一个应用程序)(都伸到/嵌入)使用指针,确保 测试 NULL 小号,否则有一个高的机会越来越 段错误访问冲突

  • 添加了[Python.Docs]:参考计数-无效的Py_DECREF(PyObject * o)语句可避免内存泄漏

  • Build(编译/链接)/ Run选项(显然,您已经跳过了这些,因为您能够运行您的程序,但是无论如何我都会列出它们-确保在处理 多个选项 时这里有一些捷径这样的项目):

    • 检查[SO]:CLR Windows窗体中的LNK2005错误(@CristiFati的答案)以获取构建 Win PE的 详细信息 __
    • 为了加快构建依赖 Python的 项目时的速度,我创建了一个 VStudio用户宏 (称为 Python35Dir- 如下图所示,指向我的 Python 3.5 安装目录)

注意事项

* 路径(“ _c: Install  x64  Python  Python  3.5_ ”)指向从官方站点下载的安装* 显然,对于 _32bit_ ,必须相应地设置路径(设置为 _32bit_ _Python_ )* 该路径包含(按预期的方式)一个 _Release_ 版本,并且只要我不需要进入 _Python_ 代码(并且只要我不弄乱内存,就像(在 _Debug中_ 构建我的应用程序时),模式))。我的 _.exe中_ 有2个 _C运行时_ -检查下面的链接,查看篡改 _MSVC运行时_ ( _UCRT_ )会发生什么: __ __ __  * [[SO]:在库中使用fstream时,可执行文件中出现链接器错误(@CristiFati的回答)](https://stackoverflow.com/questions/8528437/when-using-fstream-in-a-library-i-get-linker-errors-in-the-executable/41558269#41558269)  * [[SO]:链接到MS Visual C上的protobuf 3时出错(@CristiFati的回答)](https://stackoverflow.com/questions/35116437/errors-when-linking-to-protobuf-3-on-ms-visual-c/35118400#35118400)  * 对于 _特殊_ 情况下,我已经建立 _的Python_ 在 _调试_ 模式,得到了二进制文件,但是这不是我的1日的选择,因为它需要设置(路径)改变* 编译:

VStudio 知道 Python 包含文件的位置:

* 链接:

VStudio 知道 Python 库文件的位置(如果只需要 pythonxx * .lib ( _ PYTHONCORE
),则不需要任何额外的操作,因为 _Python
代码默认包含 PYTHONCORE
;否则,所有其余的都应在[MS.Docs中](https://docs.microsoft.com/en-
us/cpp/build/reference/dot-lib-files-as-linker-
input)指定[]:.lib文件作为链接器输入:
__

* 运行/调试-让:  * _VStudio_ 知道 _Python_ 运行时 _ **python35.dll**_ ( _PYTHONCORE_ )所在的位置( _%PATH%_ )  * 加载的 _Python_ 运行时知道其他模块的位置( _%PYTHONPATH%_ )

Experiment_test.py

import osimport shutilimport precsdef function_name(file_name):    print("Py - arg: '{}'".format(file_name))    if not os.path.isfile(file_name):        return file_name    with open(file_name, "rb") as f:        content = f.read().depre()        print("Py - Content len: {}, Content (can spread across multiple lines): '{}'".format(len(content), content))        return content

注意事项

  • 如开头所指定的几乎是虚拟的模块
  • 工作 仅与 文本 文件解码 将失败 的二进制 文件)
  • 导入未使用的模块,以确保它们正常(很明显,如果这样的 import 语句成功,则所有模块都应如此)
  • stdout 上打印一些数据(与 C ++ 端的数据匹配)
  • 位于 Python 已知 __的路径中 (上一步中为 %PYTHONPATH%
  • 有1个参数( file_name )-与问题中没有任何参数的 关键区别 (不知道这是逻辑错误还是像 错字

test_dir test_file.txt

line 0 - dummyline 1 - gainarie

输出VStudio 控制台):

Py - arg: 'test_dirtest_file.txt'Py - Content len: 33, Content (can spread across multiple lines): 'line

0 - dummy
line 1 - gainarie’
C(++) - Python call:
experiment_test.function_name(‘test_dirtest_file.txt’) returned ‘line 0 -
dummy
line 1 - gainarie’ (len: 33)
OK
Press ENTER to return…

最后说明

  • 在这种情况下(简单的一种),使用安装路径中的 PYTHONCORE 。但是在其他版本( 例如 ,另一产品中附带的版本)中, 必须在 Py_Initialize 之前 通过 Py_SetPythonHome 设置 Python 的标准库路径 。 [SO]
    虽然很旧,但运行Py_Initialize需要哪些文件?(@CristiFati的答案)可能包含一些有用的信息


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/640525.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号