Maison >développement back-end >Tutoriel Python >Une analyse approfondie des modules Python appelant C

Une analyse approfondie des modules Python appelant C

高洛峰
高洛峰original
2017-02-20 10:37:131261parcourir

Python fournit une bibliothèque C qui permet aux développeurs d'appeler facilement des modules Python à partir de programmes C. Ensuite, à travers cet article, je vais vous présenter les connaissances pertinentes sur les modules Python appelant C. Les amis qui en ont besoin peuvent s'y référer

Généralement, ceux qui ont développé des jeux savent que Lua et C peuvent être bien combinés. , apprenez des points forts de chacun et utilisez des scripts Lua. Utilisé comme une bibliothèque de liens dynamiques, il exploite à bon escient la flexibilité du développement de scripts. En tant que langage de script à usage général populaire, Python peut également le faire. Dans une application C, nous pouvons utiliser un ensemble de plug-ins pour implémenter certaines fonctions avec une interface unifiée. Généralement, les plug-ins sont implémentés à l'aide de bibliothèques de liens dynamiques. Si les plug-ins changent fréquemment, nous pouvons utiliser Python au lieu de liens dynamiques. Les plug-ins (qui peuvent être appelés bibliothèques de liens dynamiques sous forme de texte) facilitent la réécriture du code de script en fonction de l'évolution des besoins, au lieu d'avoir à recompiler et à lier des bibliothèques de liens dynamiques binaires. La flexibilité est grandement améliorée.

En tant que langage de colle, Python peut facilement appeler C, C et d'autres langages, et peut également appeler des modules Python via d'autres langages.

Python fournit une bibliothèque C qui permet aux développeurs d'appeler facilement des modules Python à partir de programmes C.

Pour une documentation spécifique, veuillez vous référer au guide officiel :

Intégrer Python dans une autre application

Méthode d'appel

1 lien vers la bibliothèque d'appel Python

Le répertoire d'installation de Python contient déjà des fichiers d'en-tête (répertoire d'inclusion) et des fichiers de bibliothèque (python27.lib sous Windows).

Vous devez créer un lien vers cette bibliothèque avant de l'utiliser.

2 Appelez directement l'instruction Python

<code class="language-cpp hljs ">#include "python/Python.h"
int main()
{
Py_Initialize(); ## 初始化
PyRun_SimpleString("print &#39;hello&#39;");
Py_Finalize(); ## 释放资源
}
</code>

3 Chargez le module Python et appelez la fonction

~/ répertoire test Contient test.py :

<code class="language-python hljs ">def test_add(a, b):
print &#39;add &#39;, a, &#39; and &#39;, b
return a+b</code>

, vous pouvez appeler la fonction test_add via le code suivant :

<code class="language-cpp hljs ">#include "python/Python.h"
#include <iostream>
using namespace std;
int main()
{
Py_Initialize(); // 初始化
// 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
string path = "~/test";
string chdir_cmd = string("sys.path.append(\"") + path + "\")";
const char* cstr_cmd = chdir_cmd.c_str();
PyRun_SimpleString("import sys");
PyRun_SimpleString(cstr_cmd);
// 加载模块
PyObject* moduleName = PyString_FromString("test"); //模块名,不是文件名
PyObject* pModule = PyImport_Import(moduleName);
if (!pModule) // 加载模块失败
{
cout << "[ERROR] Python get module failed." << endl;
return 0;
}
cout << "[INFO] Python get module succeed." << endl;
// 加载函数
PyObject* pv = PyObject_GetAttrString(pModule, "test_add");
if (!pv || !PyCallable_Check(pv)) // 验证是否加载成功
{
cout << "[ERROR] Can&#39;t find funftion (test_add)" << endl;
return 0;
}
cout << "[INFO] Get function (test_add) succeed." << endl;
// 设置参数
PyObject* args = PyTuple_New(2); // 2个参数
PyObject* arg1 = PyInt_FromLong(4); // 参数一设为4
PyObject* arg2 = PyInt_FromLong(3); // 参数二设为3
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
// 调用函数
PyObject* pRet = PyObject_CallObject(pv, args);
// 获取参数
if (pRet) // 验证是否调用成功
{
long result = PyInt_AsLong(pRet);
cout << "result:" << result;
}
Py_Finalize(); ## 释放资源
return 0;
}
</iostream></code>

Passer des paramètres

1 C Passer des paramètres à Python

Les paramètres Python sont en fait des tuples, donc passer des paramètres revient en fait à construire un tuple approprié.

Il existe deux méthodes couramment utilisées :

Utilisez PyTuple_New pour créer un tuple et PyTuple_SetItem pour définir la valeur du tuple

<code class="language-cpp hljs ">PyObject* args = PyTuple_New(3);
PyObject* arg1 = Py_BuildValue("i", 100); // 整数参数
PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮点数参数
PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串参数
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
PyTuple_SetItem(args, 2, arg3);</code>

Utilisez directement Py_BuildValue pour construire des tuples

<code class="language-cpp hljs ">PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello");
PyObject* args = Py_BuildValue("()"); // 无参函数</code>

Pour les chaînes de format telles que i, s, f, veuillez vous référer à la chaîne de format

2 Convertir la valeur de retour Python

Ce que vous obtenez lorsque vous appelez Python sont des objets PyObject, vous devez donc utiliser certaines fonctions de la bibliothèque fournie par Python pour convertir la valeur de retour en C, telles que PyInt_AsLong, PyFloat_AsDouble , PyString_AsString, etc.

Vous pouvez également utiliser la fonction PyArg_ParseTuple pour analyser la valeur de retour sous forme de tuple.

PyArg_Parse est également une fonction de conversion très pratique à utiliser.

PyArg_ParseTuple et PyArg_Parse utilisent des chaînes de format

Notes

Vous devez basculer le répertoire de travail Python vers l'emplacement du module est localisé Le chemin est chargé en fonction du nom du module au lieu du nom du fichier. Le chargement du module ou le chargement de la fonction doit être vérifié avec succès, sinon cela peut provoquer une erreur de pile et provoquer le crash du programme. Vous devez utiliser Py_DECREF (PyObject*. ) pour déréférencer l'objet (pour le garbage collection Python)

Ce qui précède est la connaissance des modules Python appelant en C introduite par l'éditeur. J'espère que cela sera utile à tout le monde !

Pour une analyse plus approfondie des modules Python appelant C, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn