Compiling a dll for 64-bits W7 with cygwin and mingw-w64

F

François Rappaz

With XP I could use the following command to successfully get a dll
for a JNI application, from the Cygwin shell:
g++ -w -mno-cygwin -I"$jdk/include" -I"$jdk/include/win32" -Wl,--add-
stdcall-alias -shared -o kbhook.dll kbhook.cpp

gives a 27 KB kbhook.dll, that works ok.

With Windows 7, I have setup mingw64-x86_64gcc-g++ in my cygwin
framework. When I run the following, from Cygwin:
x86_64-w64-mingw32-g++ -w -mno-cygwin -I"$jdk/include" -I"$jdk/
include/win32" -Wl,--add-stdcall-alias -shared -o kbhook64.dll
kbhook.cpp

I have a kbhook64.dll file which is 118 kB.
However I still have an error when I tried to use it with my java
program.

Exception in thread "main" java.lang.UnsatisfiedLinkError: U:\docs\OA
\articles\z
lib\kbhook\kbhook.dll: The specified path is invalid
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.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at ch.unifr.dokpe.shortkeys.KbHook.<clinit>(KbHook.java:15)
at ch.unifr.dokpe.shortkeys.KbListener.<init>(KbListener.java:
73)
at ch.unifr.dokpe.shortkeys.KbListener.main(KbListener.java:
317)

Does anybody has a clue on how to correct this ? (beside of using my
old dll with using a 32Bits JRE)
Francois
 
R

Roedy Green

Does anybody has a clue on how to correct this ? (beside of using my
old dll with using a 32Bits JRE)

here is my ant script for compiling JNI with Windows Express (free)
It only 32-bit. However, the SET vars might jostle something in your
mind.


DevEnvDir=F:\Program Files (x86)\Microsoft Visual Studio
10.0\Common7\IDE\
INCLUDE=F:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include;C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\Include;E:\Program Files
(x86)\Java\jdk1.7.0\include;E:\Program Files
(x86)\Java\jdk1.7.0\include\win32
JAVA_HOME=E:\Program Files\java\jdk1.7.0
LIB=F:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\lib;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib
LIBPATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Windows\Microsoft.NET\Framework\v3.5;F:\Program
Files (x86)\Microsoft Visual Studio 10.0\VC\LIB;
VS100COMNTOOLS=F:\Program Files (x86)\Microsoft Visual Studio
10.0\Common7\Tools\



<?xml version="1.0"?>
<!-- REBUILD.XML simple pcclock 7.7 build that presumes all files are
already in the project directory. -->
<!-- Build with ant -f rebuild.xml zip jet -->
<!-- Compile and jar pcclock using ANT -->
<!-- Invoke with [ant clean] to erase class files and start over. -->
<!-- Invoke with [ant compile] to just compile. -->
<!-- Invoke with [ant javah] to regenerate jni *.h files. -->
<!-- Invoke with [ant javadoc] to generate javadoc. -->
<!-- Invoke with [ant jar] to compile and create jar files. -->
<!-- For details of ANT use, see http://mindprod.com/jgloss/ant.html
-->

<!-- D E F I N I T I O N S -->
<!-- ANT.project.dir is com/mindprod/pcclock -->
<!-- basedir is E:/ -->
<project name="pcclock" basedir="E:/" default="jar">

<!-- C L E A N -->
<target name="clean">
<echo message=" ::: pcclock ::: deleting files to force
regeneration." />
<delete>
<fileset dir="com/mindprod/pcclock" includes="**/*.class" />
<fileset dir="com/mindprod/pcclock" includes="**/*.jar" />
<!-- leave Jet *.exe. Old versions are still useful during the
build. -->
</delete>
</target>

<!-- C O M P I L E -->
<target name="compile">
<echo message=" ::: pcclock ::: compiling Java tree with
target=1.5" />
<javac source="1.5" target="1.5" srcdir="com/mindprod/pcclock"
sourcepath="${basedir}" classpath="${basedir}" debug="on"
includeAntRuntime="false">
<compilerarg value="-Xlint:unchecked" />
<compilerarg value="-Xlint:fallthrough" />
<compilerarg value="-Xlint:deprecation" />
</javac>
</target>

<!-- J A V A H -->
<target name="javah" depends="compile">
<echo message=" ::: pcclock ::: building jni stubs." />
<javah class="com.mindprod.pcclock.PCClock"
outputfile="com/mindprod/pcclock/nativepcclock/pcclock.h" />
<echo message="You must compile the C/C++ JNI manually, copy to
java.libary.path somewhere" />
</target>

<!-- G A T H E R -->
<target name="gather" depends="compile">
<!-- nothing to do for non-distributed build -->
</target>

<!-- J A R -->
<!-- Make apache-ant-1.8.1\lib\GenJar.jar known to ANT -->
<!-- See http://mindprod.com/jgloss/genjar.html for details -->
<taskdef resource="genjar.properties" />

<target name="jar" depends="gather">
<echo message=" ::: pcclock ::: genjar finding
dependencies and creating jar." />
<genjar jarfile="com/mindprod/pcclock/pcclock.jar">
<!-- include all classes in the package -->
<class>
<fileset dir="${basedir}">
<!-- include all the classes in com/mindprod/pcclock -->
<include name="com/mindprod/pcclock/*.class" />
<!-- all dependent classes will be automatically included -->
</fileset>
</class>
<resource
file="com/mindprod/pcclock/nativepcclock/Release/nativepcclock.dll"
package="" />
</genjar>

<!-- S I G N -->
<!-- get _your_ password from set jarsignerpassword=sesame -->
<!-- get _your_ code-signing certificate from set
cert=mindprodcert2011dsa -->
<property environment="env" />
<signjar jar="com/mindprod/pcclock/pcclock.jar"
alias="${env.cert}" keystore="${env.keystore}/.keystore"
storepass="${env.jarsignerpassword}" />
</target>

<!-- P O S T J A R -->
<target name="postjar" depends="jar">
<!-- nothing to do -->
</target>

<!-- J E T -->
<!-- Dummy. Not using Jet -->
<target name="jet">
</target>

<!-- P R E J A V A D O C . -->
<target name="prejavadoc">
<echo message=" ::: pcclock ::: avoid regenerating Javadoc
if already done." />
<uptodate property="javadoc.uptodate"
targetfile="com/mindprod/pcclock/javadoc/index.html">
<srcfiles dir="com/mindprod/pcclock" includes="**/*.java" />
</uptodate>
</target>

<!-- J A V A D O C -->
<target name="javadoc" depends="prejavadoc" unless="javadoc.uptodate">
<echo message=" ::: pcclock ::: generating Javadoc." />
<!-- prepare javadoc -->
<javadoc
author="true"
destdir="com/mindprod/pcclock/javadoc"
packagenames="com.mindprod.pcclock.*"
sourcepath="E:/"
use="true"
access="package"
version="true" />
</target>

<!-- Z I P -->
<target name="zip" depends="javadoc,jar">
<!-- not distributing a zip -->
</target>

<!-- P O S T Z I P -->
<target name="postzip" depends="zip,postjar">
<!-- not distributing a zip -->
</target>
</project>
 
F

François Rappaz

Thanks for replying.

The script just says
<echo message="You must compile the C/C++ JNI manually, copy to
java.libary.path somewhere" />

Could you be more specific ?

Francois
 
L

Lew

François Rappaz said:
With XP I could use the following command to successfully get a dll
for a JNI application, from the Cygwin shell:
g++ -w -mno-cygwin -I"$jdk/include" -I"$jdk/include/win32" -Wl,--add-
stdcall-alias -shared -o kbhook.dll kbhook.cpp

gives a 27 KB kbhook.dll, that works ok.

With Windows 7, I have setup mingw64-x86_64gcc-g++ in my cygwin
framework. When I run the following, from Cygwin:
x86_64-w64-mingw32-g++ -w -mno-cygwin -I"$jdk/include" -I"$jdk/
include/win32" -Wl,--add-stdcall-alias -shared -o kbhook64.dll
kbhook.cpp

I have a kbhook64.dll file which is 118 kB.
However I still have an error when I tried to use it with my java
program.

Exception in thread "main" java.lang.UnsatisfiedLinkError: U:\docs\OA
\articles\z
lib\kbhook\kbhook.dll: The specified path is invalid

Is the path valid? What is the result of
ls $(cygpath 'U:\docs\OA\articles\zlib\kbhook\kbhook.dll')
?

How is the path to the DLL specified in your code?

Why do you not use forward slashes?
 
F

François Rappaz

Is the path valid?  What is the result of
  ls $(cygpath 'U:\docs\OA\articles\zlib\kbhook\kbhook.dll')
?

How is the path to the DLL specified in your code?

Why do you not use forward slashes?

Hi
$ ls $(cygpath 'u:\docs\OA\articles\zlib\kbhook\kbhook.dll') gives
/cygdrive/u/docs/OA/articles/zlib/kbhook/kbhook.dll

in my java code I call the dll with
{System.loadLibrary("kbhook");}
as far as know the dll is searched in the system and the current
folder, where it is.
I suspect that the file produced with my compile on W7 is not a dll

Francois
 
R

Roedy Green

The script just says
<echo message="You must compile the C/C++ JNI manually, copy to
java.libary.path somewhere" />

Could you be more specific ?

This is not what you want, but it might contain a clue. Here is how to
compile C++ to create an exe file with ANT.

I forgot that I have been doing my JNI C++ compiles with the gui.


<!-- C O M P I L E -->
<target name="compile">
<echo message=" ::: honk ::: compiling C++ files." />
<exec executable="cl.exe" dir="com/mindprod/honk">
<arg value="/O2" />
<arg value="/Oi" />
<arg value="/D" />
<arg value="WIN32" />
<arg value="/D" />
<arg value="NDEBUG" />
<arg value="/D" />
<arg value="_CONSOLE" />
<arg value="/D" />
<arg value="_UNICODE" />
<arg value="/D" />
<arg value="UNICODE" />
<arg value="/EHsc" />
<arg value="/MT" />
<arg value="/Gy" />
<arg value="/W3" />
<arg value="/nologo" />
<arg value="/c" />
<arg value="/TP" />
<arg value="/errorReport:prompt" />
<arg value="honk.cpp" />
</exec>
<exec executable="link.exe" dir="com/mindprod/honk">
<arg value="/INCREMENTAL:NO" />
<arg value="/NOLOGO" />
<arg value="/MANIFEST:NO" />
<arg value="/SUBSYSTEM:CONSOLE" />
<arg value="/OPT:REF" />
<arg value="/OPT:ICF" />
<arg value="/DYNAMICBASE" />
<arg value="/NXCOMPAT" />
<arg value="/MACHINE:X86" />
<arg value="/ERRORREPORT:pROMPT" />
<arg value="/OUT:honk.exe" />
<arg value="kernel32.lib" />
<arg value="user32.lib" />
<arg value="gdi32.lib" />
<arg value="winspool.lib" />
<arg value="comdlg32.lib" />
<arg value="advapi32.lib" />
<arg value="shell32.lib" />
<arg value="winmm.lib" />
<arg value="honk.obj" />
</exec>
 
R

Roedy Green

{System.loadLibrary("kbhook");}

paths are delicate things. The tiniest typo breaks them.

see http://mindprod.com/applet/wassup.html

download and run it to dump your system properties. For Linux you
should see : instead of ; between the elements.

look particularly at:

java.library.path =
E:\sys;.;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;F:\Program
Files (X86)\jet7.2-pro\bin;E:\Program
Files\Java\jdk1.7.0\bin;E:\env;E:\sys;F:\Program
Files\JPSoft\TCMD12x64;F:\Program Files\vslick\win;F:\Program Files
(x86)\apache-ant-1.8.2\bin;F:\Program
Files\PostgreSQL\9.0\bin;E:\com\mindprod\reorg;F:\Program
Files\TortoiseSVN\bin;F:\Program Files (x86)\asm;F:\Program Files
(x86)\Microsoft Visual Studio 10.0\Common7\IDE\;F:\Program Files
(x86)\Microsoft Visual Studio 10.0\VC\BIN;F:\Program Files
(x86)\Microsoft Visual Studio
10.0\Common7\Tools;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program
Files (x86)\Microsoft SDKs\Windows\v7.0A\bin;c:\Program Files
(x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft
SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL
Server\100\DTS\Binn\
 
F

François Rappaz

paths are delicate things. The tiniest typo breaks them.

seehttp://mindprod.com/applet/wassup.html

download and run it to dump your system properties. For Linux you
should see : instead of ; between the elements.

look particularly at:

java.library.path =
E:\sys;.;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;F:\Program
Files (X86)\jet7.2-pro\bin;E:\Program
Files\Java\jdk1.7.0\bin;E:\env;E:\sys;F:\Program
Files\JPSoft\TCMD12x64;F:\Program Files\vslick\win;F:\Program Files
(x86)\apache-ant-1.8.2\bin;F:\Program
Files\PostgreSQL\9.0\bin;E:\com\mindprod\reorg;F:\Program
Files\TortoiseSVN\bin;F:\Program Files (x86)\asm;F:\Program Files
(x86)\Microsoft Visual Studio 10.0\Common7\IDE\;F:\Program Files
(x86)\Microsoft Visual Studio 10.0\VC\BIN;F:\Program Files
(x86)\Microsoft Visual Studio
10.0\Common7\Tools;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program
Files (x86)\Microsoft SDKs\Windows\v7.0A\bin;c:\Program Files
(x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft
SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL
Server\100\DTS\Binn\

At last, with the help of people on mingw-w64-
(e-mail address removed), here is the magical lines to have a dll
working with java 64 bits. Under cygwin

jdk='/cygdrive/c/Program Files/Java/Jdk1.7.0'
x86_64-w64-mingw32-g++ -w -mno-cygwin -I"$jdk/include" -I"$jdk/
include/win32" -static -shared -o foo.dll foo.cpp

I could then stripp the size of the dll with
x86_64-w64-mingw32-strip foo.dll

which gives a 88 kb file instead of 509 kb.
F.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top