overview
The same dll(tableOcr.dll) in different system win10s(win10 family series and win10 professional series ) behave different result.
build tool
1. java
2. corretto-1.8.0_302
openjdk version "1.8.0_302"
OpenJDK Runtime Environment Corretto-8.302.08.1 (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM Corretto-8.302.08.1 (build 25.302-b08, mixed mode)
3. c++11
4. visual studio 2017 (14.9)
background
I need java(x64) call my c++ func through jni, my shared library is tableOcr.dll(x64) and tableOcrJni.dll(x64) which links to tableOcr.dll; I did those steps:
build my tableOcr.dll(x64) with visual studio 2017 (14.9), windows SDk version 10.0.17763.0 in win10 professional(x64 version=10.0.18363.1440) .
TableOcrJNI.dll denpentent is tableOcr.dll,lickey_parse.dll and opencv_world430.dll(checked by x64 depend.exe)
One of tableOcrJNI.dll function is :
#ifndef OCREXPORT
# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# if defined(STATIC_LINKED)
# define OCR_EXPORT
# else
# define OCR_EXPORT __declspec(dllexport) ///! 为了动态加载动态库
//# define OCR_EXPORT ///! 为了动态加载动态库
# endif
# else
# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
# define OCR_EXPORT __attribute__ ((visibility("default")))
# else
# define OCR_EXPORT
# endif
# endif
#endif
OCR_EXPORT int _cdecl obtain_table_info_init(const char* _IN_ models
Use a test.exe(build on x64 professional win10) test win32 loadLibrary way to load tableOcrJni.dll. this dll loaded with absolute path.
It success.
Use java test program load my tableOcrJni.dll, it result in is not valid win32 IN windows 10 family series (x64 version=10.19043.1706)
addition
:
I'm pretty sure %PATH% is OK for my java, I add my dlls(all linked dlls) path E:/mydll/ in It.
I tried some solution found in google(included this palce), not helped.
I tried step 3 in win10 professional(x64 version=10.0.18363.1440) series(), it is OK.
I tried install vs 2017 on win10 family serial,and do step
all failed.
I tried build x64 corretto-1.8.0_302 jdk on x64 win10 family and do step3, failed.
It is link styple mismatch. My tableOcrJni.dll behaves same as tableOcr.dll. So I just need try anything against tableOcr.dll. TableOcr.dll link some dlls like I said, So I put tableOcr.dll to E:/mydll, put tableOcr.dll's dynamic link dlls to E:/mydllDepend, activate ENV after that. It works in Win10 x64 family series !!!! but no prove has been found that I must do that way.
It's a CPU architecture (bitness) mismatch between Java (the executable) and your .dll (pc064 <=> pc032 or viceversa). Check [SO]: Python Ctypes - loading dll throws OSError: [WinError 193] %1 is not a valid Win32 application (#CristiFati's answer) for more details on the topic.
To check Java architecture use:
[cfati#CFATI-5510-0:e:\Work\Dev\StackOverflow\q072210792]> java -version
java version "1.8.0_331"
Java(TM) SE Runtime Environment (build 1.8.0_331-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.331-b09, mixed mode)
In my case it's pc064 (064bit).
You have 2 options:
Build your .dll to match Java's architecture ([SO]: OSError: [WinError 193] %1 is not a valid Win32 application while reading custom DLL in python with CTypes (#CristiFati's answer))
Install the Java version (if available) that matches your .dll's
Since I don't know which is which, my advice is to move towards pc064.
In order to check PEs bitness, dependencies, and many more details, you could use [GitHub]: lucasg/Dependencies, or (older) Dependency Walker, or (VStudio's) DumpBin ([MS.Docs]: DUMPBIN Reference).
Related
I'm having a hard time cross-compiling an embedded Rust project for Cortex-M4 in Windows. Going through the Embedded Rust book, I understood that it is needed to install the necessary target and toolchain. I'm trying to do this as follows (in a Windows cmd session):
> rustup target add thumbv7em-none-eabihf
info: component 'rust-std' for target 'thumbv7em-none-eabihf' is up to date
> rustup toolchain install stable-thumbv7em-none-eabihf
info: syncing channel updates for 'stable-thumbv7em-none-eabihf'
info: latest update on 2021-05-10, rust version 1.52.1 (9bc8c42bb 2021-05-09)
error: target 'thumbv7em-none-eabihf' not found in channel. Perhaps check https://doc.rust-
lang.org/nightly/rustc/platform-support.html for available targets
I do not understand the above error message. I have checked the provided link, and it seems that cortex-m4 is a "tier 2" target. I am suspicious that I have used the wrong toolchain prefix, e.g. "stable"?
Of course, if I skip the above and try to build the project with cargo build, it fails while looking for the wrong linker executable, i.e.:
error: linker `link.exe` not found
|
= note: The system cannot find the file specified. (os error 2)
note: the msvc targets depend on the msvc linker but `link.exe` was not found
note: please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 was installed with the Visual C++ option
As a side note, the project builds fine on Linux and Macos.
Could someone shed some light on how to set up the toolchain and target correctly? Unfortunately, the Embedded Rust book does not dive into OS-specific toolchain installation.
I have problems with following part of code from PocoMacros.cmake file:
# CMAKE_MC_COMPILER - where to find mc.exe
if (WIN32)
# cmake has CMAKE_RC_COMPILER, but no message compiler
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
# this path is only present for 2008+, but we currently require PATH to
# be set up anyway
get_filename_component(sdk_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" REALPATH)
get_filename_component(kit_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot]" REALPATH)
get_filename_component(kit81_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot81]" REALPATH)
if (X64)
set(sdk_bindir "${sdk_dir}/bin/x64")
set(kit_bindir "${kit_dir}/bin/x64")
set(kit81_bindir "${kit81_dir}/bin/x64")
else (X64)
set(sdk_bindir "${sdk_dir}/bin")
set(kit_bindir "${kit_dir}/bin/x86")
set(kit81_bindir "${kit81_dir}/bin/x86")
endif (X64)
endif ()
find_program(CMAKE_MC_COMPILER mc.exe HINTS "${sdk_bindir}" "${kit_bindir}" "${kit81_bindir}"
DOC "path to message compiler")
if (NOT CMAKE_MC_COMPILER)
message(FATAL_ERROR "message compiler not found: required to build")
endif (NOT CMAKE_MC_COMPILER)
message(STATUS "Found message compiler: ${CMAKE_MC_COMPILER}")
mark_as_advanced(CMAKE_MC_COMPILER)
endif(WIN32)
So when trying to build library I always got an error:
message compiler not found: required to build
As you can see since my cmake generator set to "MinGW Makefiles", poco doesn't set path for directories kit_bindir, kit81_bindir and sdk_bindir.
I've tried to set -Dkit_bindir= "C:/Program Files (x86)/Windows Kits/8.1/bin/x86/" but build still fails. Also I can't preset CMAKE_MC_COMPILER, since it will be redefined anyway. Official poco tutorial seems useless.
The main question is how to avoid using message compiler by pocolib or how to predefine path to mc.exe? Thanks.
UPDATE 1
I'm using POCO release v.1.7.6. Version 1.7.7 released still nothing changed. Maybe there some good ports to CMake I could use?
UPDATE 2 thanks to #sourcedelica
For Poco 1.9.0 you just need to install Windows SDKs and then add C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\x64 to PATH after
I think I found a solution, in PocoMacros.cmake is code:
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
# this path is only present for 2008+, but we currently require PATH to
# be set up anyway
get_filename_component(sdk_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" REALPATH)
get_filename_component(kit_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot]" REALPATH)
get_filename_component(kit81_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot81]" REALPATH)
if (X64)
set(sdk_bindir "${sdk_dir}/bin/x64")
set(kit_bindir "${kit_dir}/bin/x64")
set(kit81_bindir "${kit81_dir}/bin/x64")
else (X64)
set(sdk_bindir "${sdk_dir}/bin")
set(kit_bindir "${kit_dir}/bin/x86")
set(kit81_bindir "${kit81_dir}/bin/x86")
endif (X64)
endif ()
find_program(CMAKE_MC_COMPILER mc.exe HINTS "${sdk_bindir}" "${kit_bindir}" "${kit81_bindir}"
DOC "path to message compiler")
so as you see some necessairy configurations are availabilable only if ${CMAKE_GENERATOR} is "Visual Studio", and unfortunately there is no more Windows Generators available.
As you see necessairy is mc.exe, which is available with Visual Studio, but if you don't have VS (as I don't) you need to download and install Microsoft SDKs.
Then look to settings:
get_filename_component(sdk_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" REALPATH)
set(sdk_bindir "${sdk_dir}/bin/")
you need to copy them just before:
find_program(CMAKE_MC_COMPILER MC.Exe HINTS "${sdk_bindir}" "${kit_bindir}" "${kit81_bindir}"
This worked for me and I saw:
"Configuring done
Generating done" in CMake
I'm trying to build the example code for JNI, Java Native Interface, as shown by the tutorial here: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html. The problem arises when I attempt to compile. With gcc-3 in Cygwin it was possible to use the -mno-cygwin flag to compile a stand-alone dll that did not rely on Cygwin's dlls. However, that has been depreciated in gcc-4 which is the compile that I have.
So when I add the flag to my Makefile:
gcc: error: unrecognized command line option ‘-mno-cygwin’
And when I take it out, the project compiles but returns this error when attempting to run the program:
$ java HelloJNI
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000180103bd9, pid=8604, tid=11116
#
# JRE version: Java(TM) SE Runtime Environment (8.0_45-b15) (build 1.8.0_45-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [cygwin1.dll+0xc3bd9]
This output just tells me that it can't find the cygwin dll's. Is there a way with Cygwin and gcc-4 to compile without dependency on the Cygwin dlls? I'm thinking I might revert back to gcc-3 if there's no solution here.
I have a C# application that uses SQLite and works fine on Windows.
The same Visual Studio project compiles fine in Xamarin Studio, but when running I get:
DllNotFoundException: SQLite.Interop.dll
Despite:
libsqlite3.0.dylib is in /usr/lib and also in the same folder as the executable and other DLLs
. is part of the $DYLD_LIBRARY_PATH
The executable and all SQLite-using DLLs have a matching <the_exe_or_dll_including_filename_extension>.config file containing:
<configuration>
<dllmap dll="sqlite" target="libsqlite.0.dylib" os="osx"/>
<dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="osx"/>
</configuration>
I also tried adding <dllmap dll="SQLite.Interop.dll" target="libsqlite3.0.dylib" os="osx"/>, not better.
What is the problem?
You can easily find where mono is looking for that native library by setting the MONO_LOG_LEVEL to debug and MONO_LOG_MASK filtering to only DLL related messages.
export MONO_LOG_LEVEL=debug
export MONO_LOG_MASK=dll
mono yourprogram.exe
or as a one liner so you do not have to unset env vars:
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Mono and the OS-X dynamic link editor ('man dyld' for details) does not require DYLD_LIBRARY_PATH to be set to the current directory ('.'). Note: Linux does require LD_LIBRARY_PATH to include the current directory, if that is your intention.
Move those dll map files out of the way to remove them from the equation.
Unset DYLD_LIBRARY_PATH
cd in the directory that contains your CIL based exe, dlls and native dylib(s)
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Using the native dll/shared library trace output you can track which library is not being found (or one of its dependancies) or if it is the wrong ARCH for your mono version.
If you are still having problems, we would need to know which SQLite library you are using the options that you are using to compile it (or the arch version if getting it via a Nuget). A posting your dll trace output would quickly solve things also.
Notes:
I am assuming you are using the System.Data.SQLite library and are compiling the the options "/p:UseInteropDll=true /p:UseSqliteStandard=false".
Mono includes a SQLite in it's default install, it is 32-bit on OS-X:
file /Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib
/Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib: Mach-O dynamically linked shared library i386
Assuming you are using the OS-X package installer from Mono, thus are getting the 32-bit version of Mono and thus need 32-bit versions of the native libraries.
>>file `which mono`
/usr/bin/mono: Mach-O executable i386
The /usr/lib/libsqlite3.0.dylib is a multi ARCH fat binary, so that library is not a problem, but your debug output might show another one that is a problem,
>>file /usr/lib/libsqlite3.0.dylib
libsqlite3.0.dylib: Mach-O universal binary with 3 architectures
libsqlite3.0.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
libsqlite3.0.dylib (for architecture i386): Mach-O dynamically linked shared library i386
libsqlite3.0.dylib (for architecture x86_64h): Mach-O 64-bit dynamically linked shared library x86_64
You need to build and supply SQLite.Interop.dll (or more precisely libSQLite.Interop.dylib). The Mono distribution packages don't include it, probably because it's native code and really needs to be built on the target platform.
System.Data.SQLite on Windows uses a mixed mode approach (Managed data adapter + sqlite native code in one assembly). Mono however doesn't really support mixed mode assemblies.
So on MacOS there are two alternatives when it comes to building System.Data.SQLite on Windows:
Use interop dll.
Use libsqlite.x.x.dylib.
Both of these are native code and need to be built on the Mac.
Interop is Windows com speak so it's a bit disconcerting to see it used in a MacOS context. What this native dll is is the sqlite source code compiled up with some additional native code that can be P\Invoked by System.Data.SQLite. There are some benefits to using the interop dll as opposed to the sqlite dylib.
System.Data.SQLite ships with a copy of the relevant SQLite native source code in ./SQLite.Interop/src.core. You can build the interop library by running compile-interop-assembly-release.sh on the Mac. This will build libSQLite.Interop.dylib. Drop that in beside System.Data.SQLite and you should be good to go.
If you turn on Mono dll tracing you can watch the loader (see mono 4.8.0 loader.c) searching for the dll in various locations and with various name substitutions. Eventually it finds our dylib. It is also possible to use a dllmap entry in the System.Data.SQLite.dll.config file to direct the runtime to the dll. In my case Mono is on my app bundle so I have:
<dllmap dll="SQLite.Interop.dll" target="#executable_path/../Mono/libSQLite.Interop.dylib" os="!windows"/>
The dllmap target argument is passed to dlopen() so #executable_path et al are all usable.
I prefer this approach as it goes into the repo and provides some insight into what is going on when there's a foul up.
My setup is as follows:
OS: Windows 7 Home Premium 64-bit
Eclipse: Helios 3.6.1 64-bit with CDT
and Photran
Java SE Runtime
Environment: 1.6.0_21
Java Hotspot: 64-bit Server VM
(build 17.0-b17, mixed mode)
Cygwin 1.7.2 (32-bit)
My initial test Fortran application simply prints 'Hello World!' and exits.
The code builds and runs fine, albeit with the following 2 Warnings in the Problems tab in Eclipse
Description Resource Path Location Type
Error launching external scanner info generator (gcc -E -P -v -dD C:/Users/Joe/workspace/.metadata/.plugins/org.eclipse.cdt.make.core/specs.c) HelloFortran Unknown C/C++ Problem
Error launching external scanner info generator (gcc -E -P -v -dD C:/Users/Joe/workspace/.metadata/.plugins/org.eclipse.cdt.make.core/specs.c) HelloFortran Unknown C/C++ Problem
The problem comes when trying to debug the app as a Local Fortran Application which results in this error:
cygwin warning:
MS-DOS style path detected: C:\Users\Joe\workspace\HelloFortran
Preferred POSIX equivalent is: /cygdrive/c/Users/Joe/workspace/HelloFortran
.gdbinit: No such file or directory.
CYGWIN environment variable option "nodosfilewarning" turns off this warning.
Consult the user's guide for more details about POSIX paths:
http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
auto-solib-add on
Undefined command: "auto-solib-add". Try "help".
Error: dll starting at 0x76ba0000 not found.
Error: dll starting at 0x75230000 not found.
Error: dll starting at 0x76ba0000 not found.
Error: dll starting at 0x76aa0000 not found.
[New thread 7060.0x10dc]
[New thread 7060.0x16c0]
I'm guessing the entry points aren't found because it's expecting 32-/64-bit DLL and getting the other type (correct me if I'm wrong). The GDB version is as follows:
GNU gdb 6.8.20080328 (cygwin-special)
GDB configured as "i686-pc-cygwin"
Running GDB from the command-line gives:
[New thread 5768.0x15a0]
Error: dll starting at 0x76ba0000 not found.
Error: dll starting at 0x75230000 not found.
Error: dll starting at 0x76ba0000 not found.
Error: dll starting at 0x76aa0000 not found.
[New thread 5768.0x46c]
hellofortran () at ../HelloFortran.f90:1
1 program HelloFortran
Current language: auto; currently fortran
If I'm reading that correctly the application does run in GDB and I am able to step through it, but what are the missing DLL errors about?
Dependency Walker gives the following errors for my HelloFortran.exe
Error: Modules with different CPU types were found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
The missing DLLs seem to be IESHIMS.DLL (2) which from my quick research doesn't seem to be a big issue but I don't see any reason my application would need to reference this DLL so I don't think this is leading to the errors in GDB.
All of the modules have a CPU type of x64 except for:
CYGGCC_S-1.DLL
CYGGFORTRAN-3.DLL
CYGWIN1.DLL
HELLOFORTRAN.EXE
which have a CPU type of x86
I'm concerned the missing DLL errors could harm my ability to debug my program properly (although the program will eventually run on a Unix-based HPC so I shouldn't run into these issues there since all those DLLs seem to be to do with Cygwin).
My questions:
Why do I get missing DLL errors? (Would switching to 32-bit versions of Eclipse/JVM etc fix this?)
Am I
okay to continue, or should I solve
the missing DLL errors (and if so,
how)?
Edit: My test program is as follows:
program HelloFortran
! Force variable declaration
implicit none
! Print 'Hello World!' to the main output
write (*,*) 'Hello World!'
! End program
end program HelloFortran
Why do I get missing DLL errors?
When Win/x64 sends a DebugEvent to 32-bit process about a 64-bit DLL that is part of that process, it necessarily truncates the load address (64-bit load address doesn't fit into 32-bit LPVOID). The end result is that the debugger sees a DLL load event, but can't find any DLL at that address; so warns you.
(Would switching to 32-bit versions of Eclipse/JVM etc fix this?)
No: this is fundamental to debugging any 32-bit process on x64 (at least with 32-bit debugger). I think you would get rid of the warning if you use x64 version of GDB, but I am not sure if GDB/x64 can debug 32-bit processes on Windows (x86_64 GDB has no trouble with i386 processes on Linux due to "multi-arch" support; I don't know if "multi-arch" is present in Windows version).
I'm concerned the missing DLL errors could harm my ability to debug my program properly
You shouldn't be.
I don't see any reason my application would need to reference IESHIMS.DLL
What made you think it's IESHIMS.DLL?
More likely what you see is WoW64.dll and friends.
Every 32-bit application running on Win/x64 references WoW64.