Using DLLs in Cython project - dll

I have a C++ project (lets call it base.cpp) using Armadillo library (that needs libs and dlls for BLAS and LAPACK libraries). I want to import function from this C++ project via Cython by my another python project (main.py). I am using setup.py (including all .cpp, .h and .lib files) for building the .pyd file (call it test.pyd). The building of test.pyd file is succesfull, however when I run my main.py file, during the part of importing function from test "ImportError:DLL Load failed: The specified module cannot be found" is raised. The Cython uses MSVC 2014 compiler. I have checked the directories where Windows looks for DLL files (https://msdn.microsoft.com/en-us/library/7d83bc18.aspx), but when I tried inserting there my dll files, nothing changed. My test.pyx file looks like this:
cdef extern from "base.h":
void printer()
def printer_wrapper():
printer()
where the function printer is just a function defined in base.cpp computing eigenvalues of a matrix. The main.py is just:
from test import printer_wrapper
if __name__ == '__main__':
printer_wrapper()
Do you have any suggestions where I might put my dll files in order to be found during the main.py runtime?

Related

CUDA C++ cython extension throws "DLL load failed while importing"

I have written a C++ CUDA extension of some linalg in visual studio, and I have created a .dll and .lib file. I have also created a wrapper using cython, but there is obviously some kind of dll dependency problem that I can't resolve. When I try to import the .pyd file, I get DLL load failed while importing safe: The specified module could not be found.
The following is my setup.py file:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
import os
ext_modules = [
Extension('safe',
['safe.pyx'],
language="c++",
libraries=['safe', 'cudart_static', 'cusolver', 'cublas'],
library_dirs=['.', "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v11.6\\lib\\x64"]),
]
setup(
name = 'safe',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
include_dirs=[np.get_include()]
)
And the following is the output of the dumpbin command that shows the dependencies for my dll:
cublas64_11.dll
cusolver64_11.dll
KERNEL32.dll
MSVCP140.dll
VCRUNTIME140.dll
VCRUNTIME140_1.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
I should also mention that my .lib, .dll and generally all related files are in the same directories, and the directories of the cuda dlls are added in PATH. Any help is appreciated.

CMake library file missing

I'm currently struggling with cmake.
I'm using Cmake for an embedded platform with GCC.
My project is separate into several modules. Each module is build into a static library. At link time, all of these libraries are collected and linked into one binary.
The problem: I created a new folder for some unit tests. All sources are build into a library libunit_tests.a.(I checked the library actually gets created).
However in my linker call other libraries are passed to the linker, mine however gets omitted resulting in an undefined reference error.
My folder structure looks like this
*
unit_tests/
*
unit_tests/inc
*unit_tests/src
There is one Cmake file located at
- /unit_tests/CMakeLists.txt
My actual CMakeLists.txt file is pretty basic
include_directories("./inc")
set(module_name "unit_tests")
set(MODULE_SOURCES
./inc/active_tests.h
./inc/Run_All_Tests.h ./src/Run_All_Tests.c
)
###########################
# add library
###########################
if(MODULE_SOURCES)
# add files to library
add_library("${module_name}"
${MODULE_SOURCES})
target_link_libraries("${module_name}"
-Wl,--start-group
-Wl,--end-group)
endif()
How do i pass this library to the linker to resolve the undefined reference error?
I thought this is done via add_libary and target_link_libraries?

Correctly Building Fortran Libraries And Using Them To Build Applications

I found a few previous questions regarding this, but was unable to find something specific for advice on correctly associating libraries and module files *.mod in a Makefile.
I have a project directory named project where all source files for a library are in project/src, all compiled *.mod files are placed in project/include, and static libraries are created into the directory project/lib using the following:
ar rc myLibrary.a module1.o module2.o module3.o
Following this, I create an application code (a Fortran program that uses these libraries) in the directory project/applications. I have now, at the root level (that is, inside project) created a simple shell script that can build the application. This part is where I cannot get the process to work.
Here is what I am doing:
INCLUDELIB='./include'
LINKLIB='./lib'
INCLUDEOTHER=<include directories for other math libraries>
LINKOTHER=<link directories and link flags for other math libraries>
COMPILER='ifort'
COMPOPTS=<compiler flags, currently I use none>
# building the application:
$COMPILER $COMPOPTS -c ./applications/application.f90 -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER
$COMPILER $COMPOPTS application.o -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER -o application.out
This procedure does not work, and it gives Error in opening the compiled module file. Check INCLUDE paths.
I tried a few variants of the above from my readings on the web about this, and I hope that it is not some minor/silly error that I am overlooking that is leading to this.
Any help or advise will be much appreciated.
This is the message you get when things were not done right with the library (it's not your fault!).
*.mod files are compiler-specific, but not *.o files : *.mod files of gfortran are not compatible with *.mod files of ifort. Therefore, when you build a library, you should put all your API functions and subroutines outside of the modules. For example:
don't do this:
module x
...
contains
subroutine sub_x
...
end subroutine sub_x
end module
but do this instead:
module x
...
end module
subroutine sub_x
use x
...
end subroutine sub_x
In this way you don't require the users to use mod files, and you can distribute your library as a .a or a .so archive.
In your case, the library you use was almost surely compiled with gfortran, so you are stuck with gfortran. The solution is to write another library as a wrapper around the original library. For example, do this
for each function/subroutine you need:
subroutine wrapped_sub_x(arguments)
use x
call sub_x(arguments)
end
Then, you compile your wrapper library with gfortran in a .a archive, and you link it to your project with ifort. In your project, don't forget to call your wrapper library instead of the original library.

Include .lib in a .dll, which is used by program as plugin

I am using Visual Studio 2008 trying to create a .dll. The dll uses an external library (.lib). Compiling and linking works fine (I included the paths to header/lib in the options). When my .dll is used by a program (as a plugin) it says "externalLibrary.dll missing" but there is no externalLibrary.dll, just a externalLibrary.lib.
Are there different options of linking (so the externalLibrary is already in my .dll)? Or can i simply create a .dll from the .lib? Or any other solutions to this problem?
Edit (to be more concrete):
In project properties i added
the header path # C/C++ - General - Additional Include Directories
the library path # Linker - General - Additional Library Directories
the library name # Linker - Input - Additional Dependencies (although
this doesn't change anything)
The .lib file you are using is an import library which basically means that it contains only stubs for functions/classes/... but not the actual implmentation. That implementation is in the dll. An import library is only useful for the linker as it uses it to resolve symbols. But at runtime, the actual compiled code is needed so your application/dll looks for the dll. But even if your dll is used as a plugin, it's no problem for it to depend on other dlls. So if you have the other dll I suggest you go that way. (what is 'externalLibrary' btw?, it's not normal a vendor supplies you only with an import library and not the dll)
If you really do not want to use the external dll, you'll have to find the static library for the code of 'externalLibrary'. Unlike the import library, a static library does contain all symbols complete with actual implementation etc. So after linking with a static library, your application/dll contains the code itself and does not need to resolve it at runtime.

Linking 64bit dll mingw

I'm linking a dll with some dependencies on other dlls.
I have a trouble with linking a 64bit version of my project. With 32bit version all is ok as far as I use mingw32. But when I switch to 64bit version of dependent dlls and mingw-w64 it tells the following:
c:/.../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible .\lib\native/libblabla.dll when searching for -llibblabla
Where 'libblabla' is a library I depend on. I'm absolutely sure it is 64bit version and should be compatible. Is it a bug in mingw?
Also, I tried to link using lib file, but provided lib is also considered as incompatible and the one generated by dlltool has no import table generated!
I'm totally stuck with this.
Thank you.
First, to get some possible misunderstanding out of the way:
GCC/ld can link to (properly exporting) 32-bit DLLs and .lib/.a import and static libraries.
GCC/ld should be able to link to a properly exporting 64-bit DLL or .a import or static lib, but never a 64-bit .lib file.
You aren't building/linking with -m32, are you?
By "properly exporting" I mean that dumpbin /exports or nm -t reveal exported symbols when run on the DLL.
What you should try:
Build the through a call to gcc, not any direct calls to binutils. The options -shared -o name.dll -Wl,--import-lib, libname.dll.a should get you started.
Use MinGW-w64's gendef (it's in the mingw-w64-tools directory in their SVN/sources) to generate a .def file, which you can create an import library.
If these produce no symbols in the import library, you're not exporting any symbols. Although this would be surprising as the error message says the dll is 32-bit. What does MSYS/Cygwin's file command on the dll return?