4

I'm using pybind11 to create a Python wrapper for a small C++ class.
I'm getting the following error when importing the DLL (running python -v to show Traceback):

>>> from a_py import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 657, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 556, in module_from_spec
  File "<frozen importlib._bootstrap_external>", line 1101, in create_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
ImportError: DLL load failed while importing a_py: The specified module could not be found.

The class has just two members - types from the PCL library:

class A
{
   pcl::NormalEstimation< pcl::PointXYZ, pcl::Normal> normalEstimation_;
   pcl::PointCloud<pcl::Normal>::Ptr normals_;
};

If I remove the first member I can successfully import the module from the DLL.

This is the pybind11 code:

namespace py = pybind11;

PYBIND11_MODULE(a_py, m)
{
   py::class_<A>(m, "A");
}

PCL is found using CMake: find_package(PCL REQUIRED)

This happens on both Windows and Linux with the latest PCL (1.10) and older versions too.

(Adding #define PCL_NO_PRECOMPILE before the #includes does not help.)

Update: I opened a GitHUb issue about this, since this seems like a spurious internal runtime dependency.

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137

1 Answers1

2

The error “The specified module could not be found” is a bit misleading on Windows because it means either the DLL you are trying to load or any of its dependencies cannot be located.

Windows searches for DLLs in the order and paths described here: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order but usually you have to just ensure that the DLLs you depend on are in the same folder as the DLL you are loading.

Try to open the your DLL in this tool (a more modern version of DependencyWalker): https://github.com/lucasg/Dependencies and look for DLLs which cannot be found.

mauve
  • 1,976
  • 12
  • 18
  • Thanks for the lead! ***Dependencies*** showed a dependent DLL in the bad import example: `c:\Program Files\PCL 1.10.0\bin\pcl_common.dll`. When I copy it to the output folder the class imports properly. But this is a library DLL, I don't want to copy it to my own build/output/bin folder. The strange thing is that the path to the DLL is in the `PATH` env. variable, so I presumed Python would find it. I don't know why it doesn't. – Adi Shavit Apr 23 '20 at 05:26
  • Python adds some extra flags to LoadLibraryEx which alter the search behavior: https://github.com/python/cpython/blob/1221135289306333d11db25ab20cbbd21ceec630/Python/dynload_win.c#L193 – mauve Apr 23 '20 at 13:02