Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay load python DLL when embedding python+numpy

I am building a C++ application that will call python + numpy and I would like to DELAYLOAD the python dll. I use Visual Studio 2015 on Windows with 64 bit python 3.6. The DELAYLOAD works fine as long as I am not using numpy. As soon as I call import_array(), I can no longer build with DELAYLOAD option. The linker error is

LNK1194 cannot delay-load 'python36.dll' due to import of data symbol '__imp_PyExc_ImportError'; link without /DELAYLOAD:python36.dll.

Here is my code:

// Initialize python
Py_Initialize();

// If I remove this line, I am able to build with DELAYLOAD
import_array();

Is there any way to make delay load possible when using numpy?

Alternative question: is it possible to create and fill with data a numpy.recarray without calling import_array()?

EDIT: I decided to get rid of import_array(). Here is some of the code that I use to initialize Python:

    if (!Py_IsInitialized())
    {
        // Initialize Python
        Py_Initialize();

        // Initialize threads
        PyEval_InitThreads();

        // Needed for datetime
        PyDateTime_IMPORT;

        // Needed to avoid use of Py_None, Py_True, and Py_False;
        // which cause inability to use DELAYLOAD
        HMODULE pythonDll = GetModuleHandle(L"python36.dll");
        if (pythonDll == nullptr)
        {
            throw gcnew NotSupportedException(L"GS_ERR_CannotInitialize");
        }
        PythonHelper::_pyNone = (PyObject*)GetProcAddress(pythonDll, "_Py_NoneStruct");
        PythonHelper::_pyTrue = (PyObject*)GetProcAddress(pythonDll, "_Py_TrueStruct");
        PythonHelper::_pyFalse = (PyObject*)GetProcAddress(pythonDll, "_Py_FalseStruct");
    }
like image 691
Andrey Belykh Avatar asked Jun 23 '17 20:06

Andrey Belykh


1 Answers

Is there any way to make delay load possible when using numpy?

You might not be able to use DELAYLOAD with import_array:

  1. You cannot delay load a DLL if data is imported from it (official documentation).

  2. import_array imports the module where the function-pointer table is stored and points the correct variable to it (official documentation).

I doubt you are dealing with a case of exporting classes versus exporting data members. See this, this, or this.

like image 70
sancho.s ReinstateMonicaCellio Avatar answered Oct 26 '22 03:10

sancho.s ReinstateMonicaCellio