[C++-sig] Beginner - PyObject_CallObject fails because imported module is not recognized

BERGER Christian Christian.BERGER at 3ds.com
Tue Jan 5 14:15:32 EST 2016


We have this simple (test) script that defines a function that we want to call via python's c api:

import pprint
import sys
counter= 0
def onInitialize(ctxt):
   global counter
   counter+=1
   pprint.pprint(sys.path)
   return counter

While executing this works fine from the python command line, when using PyObject_CallObject to execute 'onInitialize', we're getting an error that pprint was undefined: "name 'pprint' is not defined".
Moving the import statement into the function resolves the issue, but that seems wrong, and won't work for us (we want our customers to be able to provide their own implementation of onInitialize() and a bunch of other functions).
I'm assuming I'm missing something very basic, but I haven't found it...
The interesting thing is that the global variable counter is defined and increments as desired/expected when calling the function via PyObject_CallObject(.) repeatedly.

The environment is
Python 3.5.1 (64bit)
Win7


The source code is below, if anybody wants the vs solution, that can be provided.
Thanks for your help,
Christian



#include "stdafx.h"
#include "Python.h"

void hackIt()
{
    const char* const pTestScripts =
        "import pprint\n"
        "import sys\n"
        "counter= 0\n"
        "def onInitialize(ctxt):\n"
        "  global counter\n"
        "  counter+=1\n"
        "  pprint.pprint(sys.path)\n"
        "  return counter\n";

    Py_Initialize();
    PyObject* pModule = PyImport_AddModule("__main__");
    PyObject* pPyMainDict = PyModule_GetDict(pModule);
    _Py_static_string(PyId_string, "<string>");
    PyObject* pFileName = _PyUnicode_FromId(&PyId_string);
    PyObject* pScriptObject = Py_CompileStringObject(pTestScripts, pFileName, Py_file_input, NULL, 0);
    PyObject* pLocalDictionary = PyDict_New();
    if (pScriptObject)
    {
        PyObject* pResult = PyEval_EvalCode(pScriptObject, pPyMainDict, pLocalDictionary);
        if (NULL != pResult)
        {
            PyObject* pFxnObj = PyDict_GetItemString(pLocalDictionary, "onInitialize");
            long retval = -1;
            PyObject* pTuple = PyTuple_New(1);
            PyObject* pParam = PyLong_FromLong(42);

            PyTuple_SetItem(pTuple, 0, pParam); //tuple takes ownership of pParam
            PyObject* pResultObj = PyObject_CallObject(pFxnObj, pTuple);
            Py_XDECREF(pTuple);

           if (pResultObj)
            {
                printf("got a %ld\n", PyLong_AsLong(pResultObj));
                Py_DECREF(pResultObj);
            }
            else
            {
                PyObject* pPyErr = NULL;
                if (pPyErr = PyErr_Occurred())
                {
                    const char* pStr = NULL;
                    PyObject* pTypeObj = NULL;
                    PyObject* pValueObj = NULL;
                    PyObject* pWhatObj = NULL;
                    PyErr_Fetch(&pTypeObj, &pValueObj, &pWhatObj);
                    if (pValueObj)
                    {
                        if (PyBytes_Check(pValueObj))
                        {
                            printf("Error: %s\n", PyBytes_AsString(pValueObj));
                        }
                        if (PyUnicode_Check(pValueObj))
                        {
                            wchar_t buffer[1024];
                            PyUnicode_AsWideChar(pValueObj, buffer, 1024);
                            printf("Error: %S\n", buffer);
                        }
                    }
                    Py_XDECREF(pWhatObj);
                    Py_XDECREF(pValueObj);
                    Py_XDECREF(pTypeObj);
                }
            }
        }
    }
    Py_XDECREF(pLocalDictionary);
    Py_XDECREF(pScriptObject);
    Py_Finalize();
}

int _tmain(int argc, _TCHAR* argv[])
{
    hackIt();
    return 0;
}



This email and any attachments are intended solely for the use of the individual or entity to whom it is addressed and may be confidential and/or privileged.

If you are not one of the named recipients or have received this email in error,

(i) you should not read, disclose, or copy it,

(ii) please notify sender of your receipt by reply email and delete this email and all attachments,

(iii) Dassault Systemes does not accept or assume any liability or responsibility for any use of or reliance on this email.

For other languages, go to http://www.3ds.com/terms/email-disclaimer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20160105/6b6302d2/attachment.html>


More information about the Cplusplus-sig mailing list