我尝试使用给定的intel复制问题,但是这是不可能的,因此我创建了一个小示例(尽可能接近问题中所描述的内容)-也称为[SO]:如何创建最小的,可复制的示例(reprex(mcve))(应该包含在问题BTW中 )
因此,我在这里说明的问题是:
我正在使用(在 Win 10 x64(10.0.16299.125)上 ):
该结构包括:
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 = PyUnicode_FromString(MOD_NAME);
if (pName == NULL) {
return cleanup("PyUnicode_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 = PyUnicode_FromString(fName.c_str());
if (pValue == NULL) {
Py_DECREF(pArgs);
return cleanup("PyUnicode_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 = PyUnicode_AsUTF8(pResult);
Py_DECREF(pResult);
if (res == NULL) {
return cleanup("PyUnicode_AsUTF8 returned NULL");
} else {
cout << string("C(++) - Python call: ") << MOD_NAME << "." << FUNC_NAME << "('" << fName << "') returned '" << res << "' (len: " << len << ")" << endl;
}
}
return cleanup("OK", 0);
}
:
开头的 _ *_
如我所说,尝试简化代码(摆脱了 PyCallable_Check 测试)
尽管代码使用 _ *_
由于 Python的API ([Python.Docs]:Python嵌入在另一个应用程序)(都伸到/嵌入)使用指针,确保 ,否则有一个高的机会越来越 段错误 ( 访问冲突 )
添加了[Python.Docs]:参考计数-无效的Py_DECREF(PyObject * o)语句可避免内存泄漏
Build(编译/链接)/ Run选项(显然,您已经跳过了这些,因为您能够运行您的程序,但是无论如何我都会列出它们-确保在处理 时这里有一些捷径这样的项目):
:
* 路径(“ _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 库文件的位置(如果只需要 pythonxx * .lib ( _ ),则不需要任何额外的操作,因为 _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 os
import shutil
import codecs
def 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().decode()
print("Py - Content len: {}, Content (can spread across multiple lines): '{}'".format(len(content), content))
return content
:
test_dir \ test_file.txt :
line 0 - dummy
line 1 - gainarie
( VStudio 控制台):
Py - arg: 'test_dir\test_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_dir\test_file.txt’) returned ‘line 0 - dummy line 1 - gainarie’ (len: 33) OK Press ENTER to return…
: