I created a program which uses JNI. I compiled it, generated header file, created a corresponding C program, and created dll for it.
I am running into an exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\examples\FirstJNIExample.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at com.ankur.FirstJNIExample.(FirstJNIExample.java:9)
Could not find the main class: com.ankur.FirstJNIExample. Program will exit.
I don't know which all dlls my FirstJNIExample.dll is dependent on.
I saw in Dependency Walker that my dll is dependent on following dlls:
msvcr90.dll
kernel32.dll
and this kernel32.dll is dependent on:
ntdll.dll
I also see an error in Dependency Walker for msvcr90.dll that system can't find the file specified.
This dll is present in my system at this location: D:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT
When I thought of loading it on my own in code like this:
enter code here
System.load("D:/Program Files/Microsoft Visual Studio 9.0/VC/redist/x86/Microsoft.VC90.CRT/msvcr90.dll");
System.load("d:/examples/FirstJNIExample.dll");
I get a windows error:
Microsoft Visual C++ Runtime Library
Runtime Error!
Program: C:\Windows\system32\java.exe
R6034
An application has made an attempt to load the C runtime library incorrectly.
Please contact the application's support team for more information.
OK
And this exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Program Files\Micr
osoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT\msvcr90.dll: A dynamiclink library (DLL) initialization routine failed
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at com.ankur.FirstJNIExample.(FirstJNIExample.java:10)
Could not find the main class: com.ankur.FirstJNIExample. Program will exit.
I am just lost. So many questions:
Why my dll is dependent on msvcr90.dll?
How do I load this dll?
I never worked with dlls before.
Looks like you need a manifest, or to switch to static linking, and/or manipulate PATH.
Almost any C++ code you write on Windows will make use of the MSVC runtime. By default, that code is linked dynamically. If you use dumpbin /imports on your JNI DLL you will see the dependency.
The JRE calls LoadLibrary and not LoadLibraryEx, so it isn't good enough to have the dependency sitting right next to the JNI library. You have to have the directory containing the MSVC runtime DLL in PATH. Or, you need to link it statically, but I'm not sure this is possible with MSVC90. Or, you need to manifest it.
Related
I use Visual Studio 2017 to open cmake projects. I have a debug application which uses MDd runtime library - CMAKE_CXX_FLAGS_DEBUG:/MDd /Zi /Ob0 /Od /RTC1. When I try to link to a release static library (MD runtime) I get the following errors:
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
I can build a debug static library (MDd runtime library) and link to it but I wonder if there is any workaround for that issue ?
I have a debug application which uses MDd runtime library
/MDd means your application is using the "debug multithread-specific and DLL-specific version of the run-time library".
When I try to link to a release static library (MD runtime)
/MD means the library is using the "multithread-specific and DLL-specific version of the run-time library". That is not a "release static library", the library is using the DLL version of the CRT, and that CRT is shared with your application. This requires the debug vs. release options to match between the application build and the library build, and there is no possible way to circumvent that. From the documentation page:
All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option
I have legacy c++ code that I'm trying to re-engineer.
I want to take some part of code out of the project as a ".so" shared library and load them dynamically by "dlopen".
I have written a dynamic loading mechanism which can load new modules dynamically at runtime.
Now I want to decouple existing modules from main project.
For instance I have extracted module "X" from the main project and created shared library which can be loaded later, but some part of the main project are using module X's classes directly and I can't change them yet.
I can compile the project by using module X's header files, but linker throw out "undefined reference" error.
How can I tell c++ linker that these classes will be added later by dlopen mechanism at runtime?
note: I can link and run project by copying created ".so" file of module X in "/lib" folder and use it when linking by "-lX" flag, but if I delete this file form the /lib folder the project fails on startup.
I know if you use X's classes directly you have to link X.so to your program. But if you link X.so you can use dlopen in runtime.
What you need is called an import library. They contain small wrappers for all necessary functions and thus satisfy all static linker dependencies. At runtime these wrappers will load dynamic library if it's not yet loaded and forward execution to real implementation inside library.
Import libraries is a standard feature of Windows DLLs but they are not available out-of-the-box on Linux (or any POSIX system). You can implement wrappers by hand or use Implib.so to generate them automatically.
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.
gcc (GCC) 4.7.2
cmake version 2.8.11
Hello,
I wondering if there is a way around the following issue. I have highlighted below:
SET(GW_SOURCE_FILES
module.c
module_imp.c
module_message.c
module_config.c
module_queue.c)
# Compiles the source files to create the shared library called dlg_gw.so
ADD_LIBRARY(dlg_gw SHARED ${GW_SOURCE_FILES})
# Link additional libraries to this
TARGET_LINK_LIBRARIES(dlg_gw gc srl ${APRUTIL})
# ISSUE: Now I want to create my executable using the same source files. module.c is where my 'void main(void)' is.
# However, I have some functions in there which will also be part of the library.
# However, this will recompile the same source files all over again. I don't really like that behaviour.
ADD_EXECUTABLE(sun_gw ${GW_SOURCE_FILES})
# After the executable is created, link the libraries with it.
TARGET_LINK_LIBRARIES(sun_gw ${APR} driver dlg_gw dlg_sip dlg_ss7 dlg_isdn)
I hope you can see the issue above, as I am compiling the same source files twice. Once to create the dlg_gw library. Then again to create the executable sun_gw.
I was thinking of taking out the 'void main(void)' and putting it in a new file called runtime.c and then doing the following:
ADD_EXECUTABLE(sun_gw runtime.c)
But the above require me to change some of the source code.
Many thanks for any other suggestions,
The "OBJECT" library type introduced in CMake 2.8.8 can be used to avoid repetitive build of same files.
See http://www.cmake.org/Wiki/CMake/Tutorials/Object_Library
What is the difference between Load-time dynamic linking and Run-time dynamic linking?
Load-time Dynamic Linking
When an executable is linked to a DLL at build time the linker will not insert object code but rather it insert a stub which basically says a function of this name is located in this DLL.
Now when the executable is run, bits of the executable will be missing (i.e the function stubs) so before the program is allowed to run the program loader fixes up these missing functions by replacing them with entry points into the DLL files.
Only after all the stubs have been replace (i.e resolved) will the executable be allowed to run.
That is load time dynamic linking.
Run-time Dynamic Linking
In this case the executable was not linked to any DLL library file, so it will not contain any stubs into the dll and as such the program loader has no issue running the executable.
But the task of getting access to the function from with-in the DLL is left to the executable and can be done using the GetProcAddress Windows API.
That is run time dynamic linking.
You forgot the "homework" tag.
Load-time linking means that the DLL you're linking to is loaded when your application starts, regardless of whether or not you actually use the functionality in that DLL. Dynamic linking means that the functionality of the DLL is only loaded when it's actually needed.
Load time dynamic linking is performed by Operating System when an application is loaded. OS uses the information linker has placed in the file to locate the names of the dll, and then searches for those dlls, And if it fails to locate the Dll, it simply terminates and gives error message, otherwise, OS maps the DLL into the virtual address space of the process and increases the DLL reference count.