1

I'm trying to write some C code that calls some python code to do some data analysis, and I came upon a weird issue. If I call initialize python, call a function, finalize python, and then repeat the same 1 time, I get an access violation writing location error the second time I try to call the function. The following simple code:

#include "stdafx.h"
#include <iostream>
#include "Python.h"

int main()
{
    for (int testInc = 0; testInc < 2; testInc++)
    {
        std::cout << testInc + 1 << std::endl;
        PyObject *pName, *pModule, *pFunc, *pValue;
        Py_Initialize();
        PyRun_SimpleString("import sys");
        PyRun_SimpleString("sys.path.append(\"PathToCode\")");
        pName = PyUnicode_DecodeFSDefault("MyModuleName");
        pModule = PyImport_Import(pName);
        pFunc = PyObject_GetAttrString(pModule, "MyFunctionName");
        pValue = PyObject_CallObject(pFunc, NULL);
        printf("Result: %s\n", PyBytes_AS_STRING(PyUnicode_AsEncodedString(pValue, "ASCII", "strict")));
        Py_DECREF(pName);
        Py_DECREF(pModule);
        Py_DECREF(pFunc);
        Py_DECREF(pValue);
        Py_Finalize();
    }
    return 0;
}

(checks on Py_Object*'s being == NULL omitted for brevity, but they all pass). With the python code being:

def myFunctionName():
    import numpy
    return "Hi!"

consistently throws the error "Unhandled exception at 0x00007FFE1EBC199C (multiarray.cp35-win_amd64.pyd) in TestApplication.exe: 0xC0000005: Access violation writing location 0x000000000000000A." on the second pass through the for loop, and I'm struggling to figure out why. If I place the initialize and finalize commands outside of the for loop, then this works fine, but my understanding of these commands leads me to believe that this code should be functional. Also, if I omit the "import" command in the python script, my C code also runs fine then, leading me to believe that something weird is happening with the import. Am I misunderstanding something?

aquirdturtle
  • 2,038
  • 26
  • 20
  • 1
    0x000000000000000A is a Kern memory error for what it's worth. – Eli Sadoff May 26 '16 at 02:35
  • 2
    Why are you initializing the interpreter each time? – Ignacio Vazquez-Abrams May 26 '16 at 02:36
  • @IgnacioVazquez-Abrams I don't need to, but it seemed like the natural way to run the code I wanted to use python for when I encountered and tracked down the source of the error. In that code, every time I gather data I start a worker-thread that calls this python code, and so it made sense to me to initialize python in the thread to keep the thread self-contained. Perhaps it was a mistake or silly, but it still seems like it should work :/ – aquirdturtle May 26 '16 at 02:45
  • In principle, it should work to initialize the Python environment and finalize it multiple times in the same application. In practice, there is an impressive list of [documented caveats](https://docs.python.org/3.5/c-api/init.html#c.Py_Finalize). – John Bollinger May 26 '16 at 02:55
  • Yeah I saw that page. I'm wondering if it has something to do with the line "Dynamically loaded extension modules loaded by Python are not unloaded", despite the fact that calling "import numpy \n import numpy" should work fine. Also, the statement "Some extensions may not work properly if their initialization routine is called more than once;" is sadly vague :( – aquirdturtle May 26 '16 at 02:58
  • Python cannot be any more specific, because it is not in control of extension modules. If it were, they would not be extensions. Nevertheless, importing numpy twice into the same Python environment is not equivalent to importing numpy into two different Python environments in the same process. Based on the error message, I do suspect that this is where your problem lies. – John Bollinger May 26 '16 at 03:02
  • How would I fix or test this though? For the record, same error for other modules e.g. matplotlib. If you can only import standard modules once, it seems like that would make it impossible to initialize 2x unless you called functions that didn't use any of the same modules. – aquirdturtle May 26 '16 at 03:06

0 Answers0