1

I have some C++ code which is calling a function inside a python file. If I try to read a pickled file in the python code then I get the following error:

Exception ignored in: <module 'threading' from 'C:\\Anaconda3\\envs\\Deep_Learning\\lib\\threading.py'>
Traceback (most recent call last):
  File "C:\Anaconda3\envs\Deep_Learning\lib\threading.py", line 1289, in _shutdown
    assert tlock.locked()
SystemError: <built-in method locked of _thread.lock object at 0x000002328D1EAAA8> returned a result with an error set

Python file:

def test():
    print("In function test of pyemb.py file \n")    
    import pickle
    with open('filepath', 'rb') as f_in:
        C = pickle.load(f_in)

C++ (This file is calling the python file)

#include <stdio.h>
#include <conio.h>
#include <pyhelper.hpp>

#include <iostream>

int main()
{
    CPyInstance hInstance;


    CPyObject pName = PyUnicode_FromString("pyemb");
    CPyObject pModule = PyImport_Import(pName);       //importing the file

    if (pModule) 
    {
        std::cout << "Module load successful" << std::endl;

        CPyObject pFunc1 = PyObject_GetAttrString(pModule, "test"); //passing name of function to be called
        if (pFunc1 && PyCallable_Check(pFunc1)) // checking if not null and callable
        {
            PyObject_CallObject(pFunc1, NULL); 
        }
        else
        {
            printf("ERROR: function test didn't run as intended\n");
        }
    }
    else
    {
        printf_s("ERROR: Module not imported\n");
    }
    return 0;
}

C++(pyhelper.hpp to handle Py_Initialize ,Py_Finalize etc)

#ifndef PYHELPER_HPP
#define PYHELPER_HPP
#pragma once

#include <Python.h>

// This will take care of closing the session when CPyInstance scope ends,
// as destructor will be implicitly called to close the Py instance
class CPyInstance
{
public:
    CPyInstance()
    {
        // Setting Python home path for reading lib and bin
        Py_SetPythonHome(const_cast<wchar_t*>(L"C:\\Anaconda3\\envs\\Deep_Learning"));

        // Initializing Python interpreter
        Py_Initialize(); 

        // Setting path for python to find our python model files 
        PyRun_SimpleString("import sys");
        PyRun_SimpleString("sys.path.append(\"C:\\python_files\")");
    }

    ~CPyInstance()
    {
        Py_Finalize(); // closes the python interpreter instance
    }
};

...More code for other stuff...

How can I fix this?

Please help.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • These lines seem extraneous: `Py_SetPythonHome(const_cast(L"C:\\Anaconda3\\envs\\Deep_Learning"));` `PyRun_SimpleString("import sys");` `PyRun_SimpleString("sys.path.append(\"C:\\python_files\")");` Add the directory of your python files to your `PYTHONPATH`, this answer is helpful (https://stackoverflow.com/a/4855685/9238288) – jackw11111 May 23 '19 at 01:10
  • @jackw11111 If I add my directory to PYTHONPATH then Py_Initialize() doesnt work. Nor does it solve this problem. The reason for Py_Initialize not working properly with PYTHONPATH and PYTHONHOME is explained here: https://stackoverflow.com/questions/5694706/py-initialize-fails-unable-to-load-the-file-system-codec. Please see the third answer. – Soumya Mohanty May 24 '19 at 13:38
  • 1
    I managed to find a fix. But I am still uncertain about the cause of this error. In the python program if we give the full path like "C:\\python_files\\filename. Then it works fine. Same goes for loading pre-trained models in the python program as well. This is unusual because if python can run a program successfully then, once we embed that program in C++ it should work as well. But in this case just giving the file-name (when file is in same directory as the python program) works for python, but not when it is embedded in C++. – Soumya Mohanty May 24 '19 at 13:48

0 Answers0