Why isn't cl.exe producing a valid Windows module? - windows

I have a simple C DLL that exposes functions from a static library. The DLL compiles without errors and I can run DUMPBIN on it to see the exports. However, when I attempt to load it with DllImport in C#, it says this:
System.DllNotFoundException: Unable to load DLL 'ei.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E).
It's in the correct directory, for sure. So, I read that it might be a good idea to try Dependency Walker, in case I need to include something else. Unfortunately, when I try to open my DLL in DW, I get this:
Error: At least one file was not a 32-bit or 64-bit Windows module.
Here's my cl command:
set ERL_INTERFACE_DIR=C:\Progra~1\erl5.7.2\lib\erl_interface-3.6.2\
call vcvars32.bat
cl /I%ERL_INTERFACE_DIR%include /LD ei.c ei.lib Ws2_32.lib /link /LIBPATH:%ERL_INTERFACE_DIR%lib
What could be causing this?

I was linking with a LIB file whose name is the same as the LIB file that the compiler emits, so it was linking with itself. I just changed the name of my source file to ErlInterface.c. I would think the linker would throw up a warning or something when this happens, but it doesn't.
Anyway, I can open the DLL in Dependency Walker now, but I still can't use it with DllImport. That's for another question, though.

Related

Rust linker seeks a LIB, rather than a DLL

I'm experimenting with Rust on Windows. My code declares and calls a function in an external library.
The declaration is like this:
#[link(name = "Rvea0326nc-64")]
extern "C" {
fn WeibullSpeedProbability(wa: &f32, wk: &f32, qu: &f32, prob: &f32, theerr: &i32) -> ();
}
(It's all ByRef because the DLL is Fortran. It's built with the Intel compiler.)
Note that the file name has no extension. The DLL is in the \target\debug\deps folder of the Rust project.
According to the documentation here
https://doc.rust-lang.org/std/keyword.extern.html, this should import a DLL on Windows, but I get an error, thus:
error: linking with `link.exe` failed: exit code: 1181
<SNIP>
= note: LINK : fatal error LNK1181: cannot open input file 'Rvea0326nc-64.lib'
Sure enough, if I find and copy in the *.lib file from which the DLL was generated, everything works fine. The DLL is apparently irrelevant.
I have tried explicitly adding ".dll" to the link name, but Rust just complains that it cannot find Rvea0326nc-64.dll.lib.
Is the documentation wrong? Have I missed something? Is there a way to get Rust to work with the DLL?
Update: I found that when running the Rust-compiled executable directly, the DLL is required and the LIB is not.
Without having too much experience with FFI in Rust, I can imagine to compile your program, you will need the .lib installed on your machine, so that rustc can correctly check that the FFI function is correct. Then when the produced binary is run, it loads the .dll at runtime and uses it.
Try to see if after producing a binary with the .lib installed, that you can run that binary without the .lib installed.

dlopen - cannot open shared object file

I'm compiling a shared library with gcc and loading it using dlopen. I also pass the following to the compiler:
-fvisibility=hidden
When I compile the library WITHOUT the visibility flag, everything works perfectly. However, when I compile WITH the flag, I get the following error with dlopen:
libtest.so: cannot open shared object file: No such file or directory
The linbrary .so file exists! This seems weird to me, since if some symbols are hidden, I would expect dlsym to fail if something cannot be found. However, this already fails when loading the library (aka dlopen).
I also tried adding
__attribute__ ((visibility ("default")))
to the functions I later call (extern "C"), without any success. Does anyone know what I can do about this? Or alternatively, is there any way to debug this to figure out why dlopen fails? I do not want to remove the visibility flag, since his drastically reduces my executable size.
My lib was depended on another lib that could not be found.
You may use ldd to see the list of all dependencies, including missing.
ldd libtest.so

Error in CodeBlocks C++ program and how to set default main class

I have included the boost library in a Codeblocks c++ project.
Now, in the file
boost/function.hpp
there is an include statement
#include <boost/preprocessor/iterate.hpp>
However I get this error in Codeblocks when I try and compile:
/home/arvind/Documents/Workspace/Browser/boost/function.hpp|15|fatal error:
boost/preprocessor/iterate.hpp: No such file or directory|
What am I doing wrong here? I have simply included the Boost library as it is.
Also, I cannot find the screen/option to set the main class (which will actually execute).
How do I do this?(I am new to CodeBlocks hence this question).
Your boost includes seem to be in a non-standard/system directory : /home/arvind/Documents/Workspace/Browser, you must tell the compiler to look there (gcc -I command-line switch).
Go to Project->Build Options->Search Directories->Compiler and add the directory where boost includes are. I don't have a codeblocks install right here so this was from here.
If you can, I would recommand installing boost on your system once and for all instead of just copying files in your codeblocks workspace.

How to check if dll generated is statically or dynamically linked?

Following is my linking command:
Running Mkbootstrap for XML::SAX::ExpatXS ()
C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod -- 644 ExpatXS.bs
link -out:blib\arch\auto\XML\SAX\ExpatXS\ExpatXS.dll -dll -nologo -nodefaultlib -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE" -machine:x86 ExpatXS.obj -def:ExpatXS.def
Creating library blib\arch\auto\XML\SAX\ExpatXS\ExpatXS.lib and object blib\arch\auto\XML\SAX\ExpatXS\ExpatXS.exp
The compilation flags used are /Zi /GF /MD -c
I want to know if this dll is getting statically or dynamically linked. I referred http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx but the compiler ignores these options when I specify them in my makefile.
Thanks
Your snippet only shows the DLL getting built, it doesn't say anything about the program that uses the DLL. Which has the choice to use the DLL either way.
If you have no idea then a simple way to find out is to run Dumpbin.exe /imports on the EXE. You'll see the exports from the DLL that are actually used listed in the output. If you don't see anything then the DLL could only be dynamically loaded. Or not at all. The debugger shows notifications for DLLs that get loaded into a process, you'll see them in the Output window.
Download a copy of the windows Dependency Walker, fire it up and load your freshly minted dll.
It will show all the DLLs that your dll imports. If one of the imports has a name like msvcr<blah>.dll (e.g., msvcrt.dll, or msvcr90.dll — you get the picture), then it is using the c-runtime in a dll (which incidentally, is the recommended thing for a dll to do).

Linking FFTW into Matlab Mex file

I am trying to run FFTW code in a mex file. This is strictly for the purpose of development and testing. After some googling, I see that others have tried to do something similar and have had related problems, but I have not found any solutions. When attempting to run the mex file, Matlab tells me:
??? Error using ==>
chirpTransform.mxCta Invalid MEX-file
'\removed\my\directory\+chirpTransform\mxCta.mexw32':
The specified procedure could not be
found.
.
I am using gnumex with MinGW to build the mex file because LCC seems to have some issues. I have tried using the 32 bit DLL from the FFTW site (http://www.fftw.org/install/windows.html). I have tried using the fftwf3.dll in the Matlab 2009b bin directory. I built the dll from source using Msys/MinGW. In all cases, the results are the same. In all cases I did the following to generate the lib file.
c:\gnumex\mexdlltool.exe -d
libfftw3f-3.def -D libfftw3f-3.dll -l
libfftw3f.lib --as C:\MinGW\bin\as.exe
I also tried using the visual studio lib.exe tool and experimented with various mexdlltool flags.
It appears that I can directly call functions in the fftwf3-3.dll using Matlab's loadlibrary functionality. Since the DLL appears not to be the problem, I tried building a static version of fftwf3 and linking it directly into the mex file. I got the same results! If I remove the FFTW code, the mex file runs fine. I have just about given up at this point, and I am tyring to come up with alternative methods of testing.
I've run into this issue with other mex functions. In my experience, it typically means that there is a dependency issue. Some dependency is not located.
Here is a link to TMW's documentation on this issue:
Invalid MEX-File Error
Give it a read, and then try using dependency walker to diagnose the problem.
It's been a long time, and my setup has changed, but this works for me now. I suspect hoogamaphone was right. I probably didn't have the fftw dll in the same directory as the mex dll (and it wasn't in my path). In fact, 64 bit Matlab 2016a still gives you a warning about not being able to find the mex file when, in fact, it's a dependency that's missing.
My current setup is using the Visual Studio 2013 C++ compiler by default. As mentioned on the fftw web site, you need to generate a lib file for linking. You can run the Visual Studio command prompt from a regular command prompt like so:
"%VS120COMNTOOLS%VsDevCmd.bat"
Then run the following in the directory with the def file.
lib /machine:x64 /def:libfftw3f-3.def
And compile.
mex mxCta.c cta.c -I../fftw -L../fftw -llibfftw3f-3.lib
Perhaps another possibility is that gnumex introduced some dependency into the mex dll. I no longer recall whether I had used gnumex successfully testing other code. When using cygwin, if you don't use the mingw compiler (x86_64-w64-mingw32-gcc), you'll end up with a dependency on the cygwin1.dll.
Finally, if you use more than one compiler, make sure all the compiler flags are the same (same function calling conventions, ABI, etc). Also, Mathworks has changed the mex build procedure. In a recent project, I copied mexconfig.xml to my local directory from
C:\Users\myuser\AppData\Roaming\MathWorks\MATLAB\R2016a\mex_C_win64.xml
and edited the compiler flags like so:
COMPFLAGS="/Zp8 /GR /W3 /EHs /nologo /MD /Gz /TC"
If you use a custom build file, use the -f option.
mex mxCustom.c custom.lib -f mexconfig.xml

Resources