Search code examples
pythonc++pybind11python-embeddingpythoninterpreter

How to kill py::scoped_interpreter guard{} in pybind11


How to destroy python interpreter in pybind11 to call python function from c++ in loop

Here am getting output for the first time ,when it's come for 2nd time loop it's throwing Microsoft C++ exception: pybind11::error_already_set at memory location 0x000000A21C2FFA10.

I know the problem, that is already created interpreter still alive but I'm trying to create a new interpreter in same memory location. But how to delete/clear/kill that already created interpreter and create new interpreter?

C++ code(add.dll) `

extern "C"
{
    __declspec(dllexport) double add(double a,double b)
{
        py::initialize_interpreter();
        {
             double  result= py::module::import("pyfile").attr("addition")(a,b).cast<double>();
cout<<result<<endl;
return result;
        }
         py::finalize_interpreter();
    }         
}

` pyfile.py (python code)

def addition(a,b): return a+b;

c# code

class Program
{

    [DllImport("add.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern double add([In, MarshalAs(UnmanagedType.LPArray,SizeConst =16)] double a,double b);
    
    static void Main(string[] args)
    {
       double a=5.5;
       double b=3.5;
       for(int i=0;i<5;i++)
        {
         double result= add(a,b);
         Console.WriteLine(result);
        }

    }
}

Solution

  • Finally I found solution for this issue.I created a separate extern for creating and destroying

    C++ code

    extern "C"
    {
        __declspec(dllexport) void startInterpreter()    
        {
            py::initialize_interpreter();
        }
    }
    extern "C"
    {
        __declspec(dllexport) double add(double a,double b)
        {
            {
                double  result= py::module::import("pyfile").attr("addition")(a,b).cast<double>();
                cout<<result<<endl;
                return result;
            }
        }         
    }
    extern "C"
    {
        __declspec(dllexport) void CloseInterpreter()
        {
            py::finalize_interpreter();
        }
    }
    

    Python file(pyfile.py)

            def addition(a,b): 
                return a+b;
    

    c# code

    class Program
    {
        
        [DllImport("add.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern void startInterpreter();
    
        [DllImport("add.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern double add([In, MarshalAs(UnmanagedType.LPArray,SizeConst =16)] double a,double b);
    
        [DllImport("add.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern void CloseInterpreter();
    
        static void Main(string[] args)
        {
            double a=5.5;
            double b=3.5;
            for(int i=0;i<5;i++)
            {
                 double result= add(a,b);
                 Console.WriteLine(result);
            }
        }
    }