Pass Python object to C and back again
I'm trying to get to grips with using embedded Python from a C++ application. Specifically I want my C++ to launch some PyTorch code.

I am making some initialization function in Python to perform the device (CPU or GPU) discovery and would like to pass this back to the C++ code. The C++ will call another Python function for inference which is when the C++ will pass the device to Python.

        pFunc_init = PyObject_GetAttrString(pModule, "torch_init");
        if (pFunc_init &amp;&amp; PyCallable_Check(pFunc_init)) {
            pValue_device = PyObject_CallObject(pFunc_init, pArgs);

            if (pArgs != NULL)
                Py_DECREF(pArgs);

            if (pValue_device != NULL) {
                pFunc_infer = PyObject_GetAttrString(pModule, "torch_infer");
                if (pFunc_infer &amp;&amp; PyCallable_Check(pFunc_infer)) {
                    //
                    // TODO put object pValue_device into pArgs_device.
                    //
                    pValue_infer = PyObject_CallObject(pFunc_infer, pArgs_device);
                    if (pValue_infer != NULL) {
                        printf("Result pValue_infer: %ld\n", PyLong_AsLong(pValue_infer));
                        Py_DECREF(pValue_infer);
                    }
                }               
                Py_DECREF(pValue_device);
            }
            else {
                Py_DECREF(pFunc_init);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr, "Call failed\n");
                return 1;
            }
        }


The TODO marks where I would like to put this code. With simple Python objects I think I know what I need but how to deal with this custom Python object?

You can define a Python function "detect_device" which returns a string say "cuda" or "cpu". After that in your C++ code, you can do something like this.

PyObject *detect_device, *pArgsDevice;
detect_device  = PyObject_GetAttrString(pModule, "detect_device");
deviceObject = PyObject_CallObject(detect_device, NULL);

pArgsDevice = NULL;
pArgsDevice = PyTuple_New(1);
PyTuple_SetItem(pArgsDevice, 0, deviceObject);


PS: Wrote the answer in hurry due to some urgency. Will add explanation soon, but I think if you understand the code that you have written, you would be able to understand this. Letme know in comments about your progress. 
