简体   繁体   中英

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 && 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 && 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM