Unable to use SetDefaultDllDirectories/LOAD_LIBRARY_SEARCH_USER_DIRS

Yclept Nemo orbisvicis@gmail.com
Mon May 23 21:35:21 GMT 2022


I'm trying to add a new DLL search path. I don't have any problems with
'SetDllDirectory' but I cannot use it as the directory is not permanent; a
subsequent call will remove it. The function 'SetDefaultDllDirectories'
offers
many configuration flags, the ones I care about are:

LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
LOAD_LIBRARY_SEARCH_SYSTEM32
LOAD_LIBRARY_SEARCH_APPLICATION_DIR
LOAD_LIBRARY_SEARCH_USER_DIRS
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR

If DLL_LOAD_DIR is set then cygwin DLL lookups work as usual but any
directories added with 'AddDllDirectory' are ignored. If DLL_LOAD_DIR is not
set, then cygwin DLLs cannot be found. To use SEARCH_USER_DIRS I must omit
DLL_LOAD_DIR as well as reimplement cygwin DLL lookup by adding every
directory
(recursively) beneath "/usr/lib" and "/usr/bin" (using 'AddDllDirectory') as
well as the directory I initially wanted to add. Which at 1687 directories
is
not ideal.

I am testing with "_umath_linalg.cpython-38-x86_64-cygwin.dll" (from numpy)
and
"vtkCommonCore.cpython-38-x86_64-cygwin.dll" from VTK, both copied to a test
directory. The missing VTK libraries exist in the directory I wish to add.
They
are python modules and the module loading process is not compatible with
'SetDllDirectory'.

$ ldd _umath_linalg.cpython-38-x86_64-cygwin.dll
        ...
        cygblas-0.dll => /usr/bin/cygblas-0.dll (0x3da3a0000)
        cyglapack-0.dll => /usr/lib/lapack/cyglapack-0.dll (0x3b8040000)
        ...

$ ldd vtkCommonCore.cpython-38-x86_64-cygwin.dll
        ...
        vtkCommonCore.cpython-38-x86_64-cygwin.dll =>
/.../test/vtkCommonCore.cpython-38-x86_64-cygwin.dll (0x522a10000)
        cygvtkCommonCore.dll => not found
        cygvtkWrappingPythonCore3.8.dll => not found
        cygvtksys.dll => not found
        ...

This is my test program:

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

#include <Windows.h>
#include <libloaderapi.h>

int main(int argc, char** argv) {

    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);

    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_USER_DIRS);
    SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);

    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS);
    //SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS |
LOAD_LIBRARY_SEARCH_SYSTEM32);

    //SetDefaultDllDirectories(LOAD_WITH_ALTERED_SEARCH_PATH);

    // Cygwin paths do not work
    //AddDllDirectory(L"/bin");
    //AddDllDirectory(L"/lib");
    //AddDllDirectory(L"/usr/bin");
    //AddDllDirectory(L"/usr/lib");
    //AddDllDirectory(L"/usr/lib/lapack");
    //AddDllDirectory(L"/cygdrive/c/WINDOWS");
    //AddDllDirectory(L"/cygdrive/c/WINDOWS/SYSTEM32");
    //AddDllDirectory(L"/cygdrive/c/Users/.../test");

//AddDllDirectory(L"/cygdrive/c/Users/.../pyvenv38/lib/python3.8/site-packages/vtkmodules");

    AddDllDirectory(L"C:\\cygwin64\\bin");
    AddDllDirectory(L"C:\\cygwin64\\lib");
    //AddDllDirectory(L"C:\\cygwin64\\lib\\lapack");
    //AddDllDirectory(L"C:\\Windows");
    //AddDllDirectory(L"C:\\Windows\\System32");
    //AddDllDirectory(L"C:\\Users\\...\\test");

AddDllDirectory(L"C:\\Users\\...\\pyvenv38\\lib\\python3.8\\site-packages\\vtkmodules");


//SetDllDirectoryW(L"C:\\Users\\...\\pyvenv38\\lib\\python3.8\\site-packages\\vtkmodules");

    if (argc != 2) {
        printf("Error: one argument accepted: filepath to a DLL\n");
        return 2;
    }

    if (!argv[1][0]) {
        printf("Error: Path must not be empty\n");
        return 2;
    }

    printf("Testing dlopen with '%s'\n", argv[1]);
    void* sh = LoadLibraryA(argv[1]);
    //void* sh = LoadLibraryEx(argv[1], NULL, 0x0);
    //void* sh = dlopen(argv[1], RTLD_NOW);

    if (!sh) {
        char* dle = dlerror();
        printf("Symbol table handle was null: %s\n", dle);
        return 1;
    }
    else {
        printf("Succeeded: not null\n");
        return 0;
    }
}

Please advise.

Thanks,


More information about the Cygwin mailing list