Created
February 17, 2012 03:51
-
-
Save farces/1850444 to your computer and use it in GitHub Desktop.
Python Extending
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// py.cpp : Defines the entry point for the console application. | |
// | |
#include <Python.h> | |
#include <math.h> | |
/* This method will be exported as part of the test_embed package for use in imported | |
python modules: | |
import test_embed | |
test_embed.emb_pow(x,y) | |
*/ | |
static PyObject* emb_pow(PyObject *self, PyObject *args) { | |
int x, y; | |
if (PyArg_ParseTuple(args, "ii", &x, &y)) { | |
//this is really just an awful thing to do as an example | |
int result = pow((double)x,(double)y); | |
return Py_BuildValue("i", result); | |
} | |
return NULL; | |
} | |
/* Define which methods are members of the test_embed module for exporting */ | |
static PyMethodDef EmbMethods[] = { | |
{"emb_pow", emb_pow, METH_VARARGS, | |
"return pow(x,y)"}, | |
{NULL, NULL, 0, NULL} | |
}; | |
int main(int argc, char* argv[]) | |
{ | |
//set python home directory to somewhere easier to redistribute i.e. Python27/ relative to exe directory | |
/* | |
char pySearchPath[] = "Python27"; | |
Py_SetPythonHome(pySearchPath);*/ | |
//See: http://docs.python.org/extending/embedding.html#pure-embedding | |
PyObject *pName, *pModule, *pDict, *pFunc; | |
PyObject *pArgs, *pValue; | |
int i; | |
if (argc < 3) { | |
fprintf(stderr,"Usage: call pythonfile funcname [args]\n"); | |
return 1; | |
} | |
Py_Initialize(); | |
//create faux-module containing C++ methods for access by python scripts | |
Py_InitModule("test_embed", EmbMethods); | |
pName = PyString_FromString(argv[1]); | |
/* Error checking of pName left out */ | |
pModule = PyImport_Import(pName); | |
Py_DECREF(pName); | |
if (pModule != NULL) { | |
pFunc = PyObject_GetAttrString(pModule, argv[2]); | |
/* pFunc is a new reference */ | |
if (pFunc && PyCallable_Check(pFunc)) { | |
pArgs = PyTuple_New(argc - 3); | |
for (i = 0; i < argc - 3; ++i) { | |
pValue = PyInt_FromLong(atoi(argv[i + 3])); | |
if (!pValue) { | |
Py_DECREF(pArgs); | |
Py_DECREF(pModule); | |
fprintf(stderr, "Cannot convert argument\n"); | |
return 1; | |
} | |
/* pValue reference stolen here: */ | |
PyTuple_SetItem(pArgs, i, pValue); | |
} | |
pValue = PyObject_CallObject(pFunc, pArgs); | |
Py_DECREF(pArgs); | |
if (pValue != NULL) { | |
printf("Result of call: %ld\n", PyInt_AsLong(pValue)); | |
Py_DECREF(pValue); | |
} | |
else { | |
Py_DECREF(pFunc); | |
Py_DECREF(pModule); | |
PyErr_Print(); | |
fprintf(stderr,"Call failed\n"); | |
return 1; | |
} | |
} | |
else { | |
if (PyErr_Occurred()) | |
PyErr_Print(); | |
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); | |
} | |
Py_XDECREF(pFunc); | |
Py_DECREF(pModule); | |
} | |
else { | |
PyErr_Print(); | |
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]); | |
return 1; | |
} | |
Py_Finalize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment