This is a developer/maintainer tool to analyze Micro-Manager DLLs and help diagnose dependency issues.
- Windows
- A recent version (e.g. 2019, 2022) of Visual Studio with C++ Desktop Development workload
- Windows 10 SDK (usually installed with Visual Studio)
- Python (e.g. 3.10)
A Micro-Manager install directory (or staging directory)
Clone the source code and install by running pip install . at the source root.
If developing mmdlldeps, install into a virtual environment using pip install --editable ..
See mmdlldeps --help for usage.
Typically, run
mmdlldeps --mmreport --hide-system --hide-vc140 MM_DIRwhere MM_DIR is a Micro-Manager installation or stage directory (or any
directory containing a collection of DLLs and executables of interest).
The --mmreport option causes the output to be categorized. Without
--mmreport the output will be in a generic format (no Micro-Manager-specific
assumptions made).
The output lists each DLL, together with its knowable dependency tree. DLLs that show up as a dependency to another DLL are skipped from being listed at the top level.
DLLs are annotated:
bundled: file is present in the input directorysystem: DLL is known to be a Windows system DLL (linked via the Windows SDK, including the Universal C Runtime)vc140: DLL is known to be part of the Visual Studio 2015-2022 Redistributable (i.e., part of the C++ runtime)EXTERNAL: DLL is not bundled and not part of a known category
In addition, DLLs that call the LoadLibrary or LoadLibraryEx function are
indicated in an indented line. Note that there are other ways a DLL can depend
on external DLLs, such as via Microsoft COM (cf. mmgr_dal_NikonTI.dll) or by
running an external executable (cf. mmgr_dal_OlympusIX83.dll).
There is no substitute for detailed knowledge of Windows and Visual Studio APIs, SDKs, and runtimes, but here are some rules of thumb:
-
EXTERNALdependenciesMSVCP100.dllandMSVCR100.dllare part of the Visual C++ 2010 Redistributable (runtime). Similarly for different versions:80= 2005,90= 2008,100= 2010,110= 2012,120= 2013. Vendor DLLs that have these dependencies will generally work with device adapters built with v140 (modern Visual C++, 2015+) if (1) the correct Visual C++ Redistributable is installed and (2) the interface to the DLL is in C, not C++.- C++ APIs typically have problems (sometimes obvious, sometimes subtle) between DLLs built against different runtime versions prior to VS2015. C APIs, if designed correctly, typically avoid such problems. But neither of these statements is absolute.
-
Vendor DLLs listed as
EXTERNALusually need to be installed by the user. Either they are placed in a system directory (so that they are available to all apps), or the user needs to copy them into the Micro-Manager directory, or, in some cases, the SDK may have a special mechanism to load the DLL(s) from their installed location.-
EXTERNALDLLs may have further (transitive) non-system dependencies, which are not reported (because they are unknowable without analyzing those missing DLLs). -
How exact a version match is required for external DLLs with the version used in the build depend on the DLL. See the above comments regarding C and C++ runtime versions, but it also depends on the vendor's practices.
-
-
DLLs that are not listed as a dependency may by loaded using one of the
LoadLibraryfamily functions. These dependencies can only be manually determined (usually from the device adapter source code).-
Sometimes, the vendor provides a static library (
.lib) that handles the loading of their DLL viaLoadLibrary. In this case, the device adapter will callLoadLibraryeven if the function does not show up in the device adapter source code. -
The non-device-adapter DLLs categorized at the top level as "orphans" are mostly those loaded via
LoadLibraryby one of the device adapters, or as a JNI library by the Java runtime. Grep their names in the source code to find out.
-