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
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to