0.引言

本地配置:
Windows10;
python3.7.6,64bit;
visual studio 2019;

        最近写程序的时候一直是使用的C++,所有功能都需要手写代码来实现,不如Python方便,比如数据处理,再加上本身C++学的也很一般,于是师姐给我推了Python/C API的文档。Python/C API        因为老是会忘记以前干了啥,故在这里记录一下操作的过程。

1.VS环境配置

       直接在VS里面引用Python.h是会提醒找不到Python.h的,用Everything搜一下,在Python3x下的include目录下面。一开始查的有的博客里面说pip install python3-dev,傻乎乎的弄了好久,没用不要信。把这个目录加到 C/C++ -> 常规 -> 附加包含目录 里面去。

c 库 Python库 c++写python库_字符串

       然后是库python31_d.lib,我电脑里面没有,按照这篇博客里面说的办法搞定了。

c 库 Python库 c++写python库_字符串_02

2.运行代码

       这里参考的是这篇博客。先随便写个 hello world 程序,然后编译一下,在 Project/x64/Debug目录下会生成.exe文件。

// main.cpp

#include <iostream>
#include "Python.h"
using namespace std;
int main(){
	cout << "Hello World" << endl;
	return 0;
}

       然后在.exe同目录下写一个python程序,保存为"test_python.py"

#test_python.py

def Hello():
    print("Hello")
     
def Add(a,b):
    return  a+b

       然后修改main.cpp

/*********************************************************************************************
@ Author     : ${ lwk }
@ Software   : ${ Microsoft Visual Studio 2019 }
@ Windows SDK: ${ 10.0 }
@ Filename   : ${ main }.cpp
@ Creat Time : ${ 2020/8/19 } ${ 16:01 }
@ Last Edit  : ${ 2020/8/19 } ${ 18:02 }
**********************************************************************************************/
#include <iostream>
#include "Python.h"
using namespace std;

int main()
{
    Py_Initialize();              //初始化,创建一个Python虚拟环境
    if (Py_IsInitialized())
    {
        PyObject* pModule = NULL;
        PyObject* pFunc = NULL;
        pModule = PyImport_ImportModule("test_python");  //参数为Python脚本的文件名
        if (pModule)
        {
            pFunc = PyObject_GetAttrString(pModule, "Add");   //获取函数
            PyObject* pArgs = PyTuple_New(2);
            PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2)); //0:表示序号。第一个参数。
            PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4)); //1:也表示序号。第二个参数。i:表示传入的参数类型是int类型。
            PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);           //执行函数
            int nResult;
            PyArg_Parse(pReturn, "i", &nResult);
            cout << nResult << endl;
        }
        else
        {
            printf("导入Python模块失败...\n");
        }
    }
    else
    {
        printf("Python环境初始化失败...\n");
    }
    Py_Finalize();
}

       直接运行,成功调用Add()函数

c 库 Python库 c++写python库_Python_03


       查了点资料,记录一下Py_BuildValue的参数,来源于这篇博客

"s" (string) [char *] :将C字符串转换成Python对象,如果C字符串为空,返回NONE。
"s#" (string) [char *, int] :将C字符串和它的长度转换成Python对象,如果C字符串为空指针,长度忽略,返回NONE。
"z" (string or None) [char *] :作用同"s"。
        "z#" (string or None) [char *, int] :作用同"s#"。
        "i" (integer) [int] :将一个C类型的int转换成Python int对象。
"b" (integer) [char] :作用同"i"。
"h" (integer) [short int] :作用同"i"。
"l" (integer) [long int] :将C类型的long转换成Pyhon中的int对象。
"c" (string of length 1) [char] :将C类型的char转换成长度为1的Python字符串对象。
"d" (float) [double] :将C类型的double转换成python中的浮点型对象。
"f" (float) [float] :作用同"d"。
"O&" (object) [converter, anything] :将任何数据类型通过转换函数转换成Python对象,这些数据作为转换函数的参数被调用并且返回一个新的Python对象,如果发生错误返回NULL。
"(items)" (tuple) [matching-items] :将一系列的C值转换成Python元组。
"[items]" (list) [matching-items] :将一系列的C值转换成Python列表。
"{items}" (dictionary) [matching-items] :将一系类的C值转换成Python的字典,每一对连续的C值将转换成一个键值对。


例如:
Py_BuildValue("") None
Py_BuildValue("i", 123) 123
Py_BuildValue("iii", 123, 456, 789) (123, 456, 789)
Py_BuildValue("s", "hello") 'hello'
Py_BuildValue("ss", "hello", "world") ('hello', 'world')
Py_BuildValue("s#", "hello", 4) 'hell'
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)
Py_BuildValue("(ii)", 123, 456) (123, 456)
Py_BuildValue("(i,i)", 123, 456) (123, 456)
Py_BuildValue("[i,i]", 123, 456) [123, 456] Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456) {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))