Comparar commits

..

122 Commits

Autor SHA1 Mensagem Data
Timothy Wall 9b7ba38dc2 final 4.0 changes 2013-07-04 14:42:30 -04:00
Timothy Wall 08157deece Merge branch 'master' of github.com:twall/jna 2013-07-04 10:24:54 -04:00
Timothy Wall c7e7e2bcdc Update PublishingToMavenCentral.md 2013-07-04 10:24:26 -04:00
Timothy Wall 01ab778621 Update ReleasingJNA.md 2013-07-04 10:09:55 -04:00
Timothy Wall 312de23e5e Merge branch 'master' of github.com:twall/jna 2013-07-04 10:05:09 -04:00
Timothy Wall 792c5374d7 Update ReleasingJNA.md 2013-07-04 10:04:37 -04:00
Timothy Wall 34dea52d6c Update PublishingToMavenCentral.md 2013-07-04 10:02:32 -04:00
Timothy Wall 6f3703d00b fix line termination 2013-07-04 10:00:28 -04:00
Timothy Wall cbd4b46f9f fix paths to jna-platform.jar 2013-07-04 10:00:01 -04:00
Timothy Wall ff1109389c Update PublishingToMavenCentral.md 2013-07-04 09:51:26 -04:00
Timothy Wall c31e9cdebf Update ReleasingJNA.md 2013-07-04 09:48:30 -04:00
Timothy Wall 97449288eb ensure native bits get built for 'native' target and for tests 2013-07-03 07:23:53 -04:00
Timothy Wall 9c2aebcf3c Merge branch 'master' of github.com:twall/jna 2013-07-03 07:21:55 -04:00
Timothy Wall 54c1851db5 speed up callback lookup 2013-07-03 07:21:35 -04:00
Timothy Wall f1d0a9b688 propagate field access permissions to Union 2013-07-02 13:01:06 -04:00
Timothy Wall d62a8abb24 by default, don't build native
make Structure get/setFieldValue protected
2013-06-26 07:27:17 -04:00
Daniel Doubrovkine (dB.) 6f362b53c3 Update CHANGES.md 2013-06-23 15:46:47 -06:00
Daniel Doubrovkine (dB.) 617420eaf9 Update CHANGES.md 2013-06-23 15:46:18 -06:00
bsorrentino e0d2079802 Add support of function SHAppBarMessage from ShellApi. 2013-06-23 14:35:58 -07:00
Timothy Wall 897b318324 update win64 natives 2013-06-16 20:30:02 -04:00
Timothy Wall 1737d6addb accommodate long path names, fixes #243 2013-06-16 09:05:26 -04:00
Timothy Wall 418a53806c rename JNA load test 2013-06-15 07:15:42 -04:00
Timothy Wall 79272c76a5 make unpacked path available as a system property, track down JVM error in System.load 2013-06-15 07:05:53 -04:00
Timothy Wall d0936b0189 use jna-platform as id for platform jar 2013-06-13 03:47:31 -04:00
Timothy Wall 8db46b4c1a update freebsd natives 2013-06-13 03:39:54 -04:00
Timothy Wall c6a88f3b7f update openbsd-x86-64 natives 2013-06-13 03:38:30 -04:00
Timothy Wall 3ba1fd0975 update openbsd-x86 natives 2013-05-14 03:00:06 -04:00
Timothy Wall a3cdb5a90d leave test file behind on failure 2013-05-14 02:59:24 -04:00
Timothy Wall c6c99b8b98 abstract option for default encoding for library names 2013-06-13 03:14:17 -04:00
Timothy Wall fffe7926da replace generic bsd handling 2013-06-13 03:01:27 -04:00
Timothy Wall 285e5305cb remove generic bsd placeholders 2013-06-13 02:49:33 -04:00
Timothy Wall b9fa73ce7a add bsd targets 2013-06-13 02:48:26 -04:00
Timothy Wall d5669d2ae4 fix javadoc warnings 2013-06-13 02:23:31 -04:00
Timothy Wall 3db7fc10ec rename platform.jar to jna-platform.jar 2013-06-13 02:23:18 -04:00
Timothy Wall 2fb4c9b683 add more test coverage 2013-06-11 05:03:32 -04:00
Timothy Wall 766db7a318 fix formatting 2013-06-11 04:52:50 -04:00
Timothy Wall e8d4a3e6c0 Fix varargs tests 2013-06-11 04:50:03 -04:00
Timothy Wall 9ac8de0f5d add some Function tests 2013-06-11 04:36:35 -04:00
Timothy Wall fed3b9f432 check for invalid Structure.ByReference usage 2013-06-11 04:04:47 -04:00
Timothy Wall 3e55136c6a add license info files 2013-06-08 09:05:03 -04:00
Timothy Wall 2d7971a429 fix alignment on osx/ppc 2013-06-06 21:49:14 -04:00
Timothy Wall acf06d725f update sunos-x86* natives 2013-06-04 23:45:59 -04:00
Timothy Wall e5dcc56056 update w32ce-arm natives 2013-06-04 23:29:12 -04:00
Timothy Wall ce96234b72 Merge branch 'master' of github.com:twall/jna 2013-06-04 22:59:01 -04:00
Timothy Wall 3b8fe3b011 update android natives 2013-06-04 22:58:38 -04:00
Timothy Wall 82561550e8 update sunos natives 2013-06-05 03:01:36 +02:00
Timothy Wall 631920d41e update darwin natives 2013-06-04 18:25:45 -04:00
Timothy Wall 6021064040 Merge branch 'master' of github.com:twall/jna 2013-06-04 18:16:52 -04:00
Timothy Wall 0547a9c3e2 update linux-arm natives 2013-06-04 18:16:35 -04:00
Timothy Wall a1fe8ce22c update linux-x86 natives 2013-06-04 17:59:20 -04:00
Timothy Wall 5e56b8565a update win64 natives 2013-06-04 08:49:03 -04:00
Timothy Wall 16d4db1790 fix snprintf on windows 2013-06-04 08:44:14 -04:00
Timothy Wall 32442cd2c4 revise last error checking 2013-06-04 03:29:16 -04:00
Timothy Wall 2ac6c86266 Merge branch 'master' of github.com:twall/jna 2013-06-02 18:43:22 -04:00
Timothy Wall 5664101490 fix broken test on XP 2013-06-02 18:42:56 -04:00
Timothy Wall d2dda4abb6 update win32 natives 2013-06-02 18:42:42 -04:00
Timothy Wall 1f878f01f7 Merge branch 'master' of github.com:twall/jna 2013-06-02 19:53:21 +02:00
Timothy Wall bf28737ebd update sparc/v9 natives 2013-06-02 19:52:40 +02:00
Timothy Wall 7fb2c1b041 fix w32 compile error 2013-06-02 13:50:48 -04:00
Timothy Wall 4f3dcfdf4b update docs 2013-06-02 09:18:27 -04:00
Timothy Wall 13b2d7c0c1 Merge branch 'amd64-pthread-cleanup' of github.com:twall/jna 2013-06-02 08:45:33 -04:00
Timothy Wall 2239bdfdfd improve library load debugging 2013-06-02 08:44:32 -04:00
Timothy Wall c6151c3775 ensure native library found in jar 2013-06-02 08:34:03 -04:00
Timothy Wall 0387196f85 fix library load error w/unicode 2013-06-02 14:18:32 +02:00
Timothy Wall c7e7798979 fix amd64 native thread cleanup test 2013-05-30 10:42:09 -04:00
Timothy Wall aa80c8d19f Merge branch 'amd64-pthread-cleanup' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-30 08:03:06 -04:00
Timothy Wall 02d5f47380 Merge branch 'master' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-30 07:42:21 -04:00
Timothy Wall 75f3ed2d5a revise thread termination flag logic 2013-05-30 07:41:24 -04:00
Timothy Wall 4e5afb4940 make 32-bit win32 MSVC comment explicit 2013-05-30 07:09:55 -04:00
Timothy Wall 85793114d4 fix #237, LastErrorException/getLastError thread-safe errno on AIX 2013-05-30 07:00:30 -04:00
Timothy Wall 708e76473a Merge branch 'master' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-30 06:57:43 -04:00
Timothy Wall 2b8773a8f0 fix padding on ppc 2013-05-29 23:55:12 -04:00
Timothy Wall 962ae7998e fix broken test 2013-05-29 23:24:45 -04:00
Timothy Wall 8f199788a5 force gcc to 32-bit mode for i386 builds on amd64 2013-05-29 21:24:43 -04:00
Timothy Wall caaddd1179 add thread termination flags and checking 2013-05-29 20:43:26 -04:00
Timothy Wall 3704b23a71 auto-strip profiler prefix set in jna.profiler.prefix 2013-05-28 22:49:20 -04:00
Timothy Wall c596f9f7d5 add explicit test for direct mapping use of supplied function mapper 2013-05-28 22:18:21 -04:00
Timothy Wall f6208e71f4 Merge branch 'master' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-28 07:00:30 -04:00
Timothy Wall 85a3cda5c8 update win32-x86 natives 2013-05-27 23:09:32 -04:00
Timothy Wall 6c591c38d9 fix failing test on XP 2013-05-27 23:08:18 -04:00
Timothy Wall 15aac21e2b restore gcc as default win32 32-bit build 2013-05-27 22:22:17 -04:00
Timothy Wall e0441a356d fix failing test 2013-05-27 16:20:58 -04:00
Timothy Wall f3da8161aa verify proper module handle for dll callbacks 2013-05-27 16:14:38 -04:00
Timothy Wall 609e3e459b fix dll callbacks inline asm with msvc 2013-05-27 15:11:55 -04:00
Timothy Wall 8638bb57f9 fix 32-bit build under MSVC 10 2013-05-27 07:56:05 -04:00
Timothy Wall d11084ce0d Merge branch 'master' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-27 07:16:08 -04:00
Timothy Wall 1ae335c7da update win64 natives 2013-05-26 17:56:55 -04:00
Timothy Wall 99529821b4 Merge branch 'master' of github.com:twall/jna 2013-05-26 17:52:52 -04:00
Timothy Wall d551e656cb fix win64 compile warnings 2013-05-26 09:57:45 -04:00
Timothy Wall ba49b166fb add test for GetLastError interception 2013-05-26 09:57:28 -04:00
Timothy Wall a3e002c1db fix w32 test 2013-05-26 09:20:32 -04:00
Timothy Wall 02601e4f7c Merge branch 'master' of github.com:twall/jna 2013-05-25 20:23:51 -04:00
Timothy Wall e2349e4bf6 expand test coverage 2013-05-25 20:11:43 -04:00
Timothy Wall 87afaf44f7 fix javadoc warnings 2013-05-25 19:29:26 -04:00
Timothy Wall bb913b171d add missing methods on opaque pointer
fix NPE
2013-05-25 19:07:07 -04:00
Daniel Doubrovkine (dB.) 975063a28f Fixed links, consistent tense. 2013-05-25 14:29:03 -03:00
Daniel Doubrovkine 8e44c82096 Merged from master. 2013-05-25 13:17:17 -04:00
Daniel Doubrovkine (dB.) 7a33f0b43e Added a note on \r. 2013-05-25 13:53:53 -03:00
Daniel Doubrovkine (dB.) cfdf20f4b7 Clarified Win64 64-bit builds. 2013-05-25 13:48:22 -03:00
Timothy Wall 13207caab6 update clover 2013-05-24 23:31:37 -04:00
Timothy Wall 980b86e2c5 fix test 2013-05-24 23:31:20 -04:00
Timothy Wall c6afe5f73d check for options caching 2013-05-24 08:17:57 -04:00
Timothy Wall 5c48942bda clean up synchronization around options loading 2013-05-24 00:08:57 -04:00
Timothy Wall 82c032329a Merge pull request #234 from dblock/eclipse-build
Fix: Eclipse project build.
2013-05-23 15:06:57 -07:00
Timothy Wall 2a2bdbe60c merge from upstream 2013-05-22 22:36:55 -04:00
Timothy Wall 9414757638 update linux-arm natives 2013-05-22 22:29:56 -04:00
Timothy Wall 253dc5abae work around linux-arm class incompatibility bug in StructureTest 2013-05-22 22:27:56 -04:00
Timothy Wall 296185c0ba fix FP callback args on ARM 2013-05-22 21:12:56 -04:00
Daniel Doubrovkine 70cff3e17a Fix: Eclipse project build. 2013-05-22 18:02:54 -04:00
Timothy Wall 78969b8050 avoid static field initialization bug 2013-05-21 15:19:13 -04:00
Timothy Wall d90f6e3346 fix typo 2013-05-21 14:02:48 -04:00
Timothy Wall 8f99db35dd fix struct padding test on linux-arm 2013-05-21 13:45:38 -04:00
Timothy Wall b5759955d5 bump versions 2013-05-21 13:26:40 -04:00
Timothy Wall adafa3b2c4 last error now always preserved 2013-05-20 23:33:24 -04:00
Timothy Wall 55778824f3 Merge branch 'master' of github.com:twall/jna into amd64-pthread-cleanup 2013-05-12 09:03:59 -04:00
Trejkaz d2159d70e3 Fixing compilation issues in Kernel32UtilTest 2013-05-07 20:41:20 +10:00
Trejkaz 6a06656c16 Merge branch 'master' of https://github.com/twall/jna
Pulling master back to get compilation fixes.
2013-05-07 20:39:27 +10:00
Timothy Wall 3fa90d76f5 update linux amd64 natives 2013-05-04 11:51:59 -04:00
Timothy Wall bfea982d45 update linux-x86-64 natives 2013-05-04 11:46:43 -04:00
Timothy Wall 78d70e760e update linux-x86 natives 2013-06-02 13:35:36 -04:00
Timothy Wall b7a299f42a amd64/linux pthread investigations 2013-05-04 11:38:12 -04:00
Trejkaz 136653a644 GetLogicalProcessorInformation and associated structs 2013-05-01 13:24:31 +10:00
119 arquivos alterados com 5132 adições e 3739 exclusões
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
<classpathentry kind="src" output="build.eclipse/test-classes" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="C:/GitHub/jna-3.5.1.jar"/>
<classpathentry kind="lib" path="lib/test/reflections-0.9.8.jar"/>
<classpathentry kind="output" path="build.eclipse/classes"/>
</classpath>
+1
Ver Arquivo
@@ -18,3 +18,4 @@ dist/src-mvn.zip
dist/out-of-date.jar
perf*.txt
native/libffi/doc/libffi.info
junit-*
+678 -666
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
JNA is dual-licensed under 2 alternative Open Source/Free
licenses: LGPL 2.1 and Apache License 2.0. (starting with
JNA version 3.6.0).
JNA version 4.0.0).
What this means is that one can choose either one of these
licenses (for purposes of re-distributing JNA; usually by
+12
Ver Arquivo
@@ -0,0 +1,12 @@
This copy of JNA is licensed under the
Apache (Software) License, version 2.0 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivate works.
You may obtain a copy of the License at:
http://www.apache.org/licenses/
A copy is also included in the downloadable source code package
containing JNA, in file "ASL2.0", under the same directory
as this file.
+13
Ver Arquivo
@@ -0,0 +1,13 @@
This copy of JNA is licensed under the
Lesser General Public License (LGPL), version 2.1 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivate works.
You may obtain a copy of the License at:
http://www.gnu.org/licenses/licenses.html
A copy is also included in the downloadable source code package
containing JNA, in file "LGPL2.1", under the same directory
as this file.
+7 -7
Ver Arquivo
@@ -3,7 +3,7 @@
Java Native Access (JNA)
========================
The definitive JNA reference (including an overview and usage details) is in the [JavaDoc](http://twall.github.com/jna/3.5.2/javadoc/). Please read the [overview](http://twall.github.com/jna/3.5.2/javadoc/overview-summary.html#overview_description). Questions, comments, or exploratory conversations should begin on the [mailing list](http://groups.google.com/group/jna-users), although you may find it easier to find answers to already-solved problems on [StackOverflow](http://stackoverflow.com/questions/tagged/jna).
The definitive JNA reference (including an overview and usage details) is in the [JavaDoc](http://twall.github.com/jna/4.0/javadoc/). Please read the [overview](http://twall.github.com/jna/4.0/javadoc/overview-summary.html#overview_description). Questions, comments, or exploratory conversations should begin on the [mailing list](http://groups.google.com/group/jna-users), although you may find it easier to find answers to already-solved problems on [StackOverflow](http://stackoverflow.com/questions/tagged/jna).
JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java code - no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes. Access is dynamic at runtime without code generation.
@@ -18,10 +18,10 @@ JNA includes a platform library with many native functions already mapped as wel
Download
========
Version 3.5.2
Version 4.0
* [jna.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/3.5.2/jna-3.5.2.jar)
* [platform.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/platform/3.5.2/platform-3.5.2.jar)
* [jna.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/4.0.0/jna-4.0.0.jar)
* [jna-platform.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/platform/4.0.0/jna-platform-4.0.0.jar)
Features
========
@@ -79,12 +79,12 @@ Using the Library
* [Platform Library](https://github.com/twall/jna/blob/master/www/PlatformLibrary.md)
* [Direct Method Mapping](https://github.com/twall/jna/blob/master/www/DirectMapping.md) (Optimization)
* [Frequently Asked Questions (FAQ)](https://github.com/twall/jna/blob/master/www/FrequentlyAskedQuestions.md)
* [Avoiding Crashes](http://twall.github.com/jna/3.5.2/javadoc/overview-summary.html#crash-protection)
* [Avoiding Crashes](http://twall.github.com/jna/4.0.0/javadoc/overview-summary.html#crash-protection)
Primary Documentation (JavaDoc)
===============================
The definitive JNA reference is in the [JavaDoc](http://twall.github.com/jna/3.5.2/javadoc/).
The definitive JNA reference is in the [JavaDoc](http://twall.github.com/jna/4.0.0/javadoc/).
Developers
==========
@@ -108,7 +108,7 @@ License
=======
This library is licensed under the LGPL, version 2.1 or later, and (from
version 3.6 onward) the Apache Software License, version 2.0. Commercial
version 4.0 onward) the Apache Software License, version 2.0. Commercial
license arrangements are negotiable.
*NOTE: Oracle is not sponsoring this project, even though the package name (com.sun.jna) might imply otherwise.*
+3 -2
Ver Arquivo
@@ -51,6 +51,9 @@
referenced. (not really common)
* eliminate type conversion contexts; these are almost entirely unused and
more complicated than just wrapping a native mapping in a utility function
* direct non-primitive array arguments (String[], Pointer[], NativeMapped[])
* auto-generate direct mappings/bindings on a per-method basis (perform a
method register on first call to an interface-mapped function) with
@@ -64,12 +67,10 @@
and forth multiple times). This also makes it easer to perform conversions
(no native changes required).
* direct/raw non-primitive array arguments (String[], Pointer[], NativeMapped[])
* ppc64 direct/raw failures (multiple)
* direct calls on ppc to varargs (callbacks) with FP args fail; avoid them for
now
* Callback.PostCallWrite.write() cf PostCallRead
* eliminate type conversion contexts; these are almost entirely unused
* universal GCC build w/cross-compile (needs cross compilers...)
* return Pointer.SIZE/LONG_SIZE/WCHAR_SIZE in bits (for consistency with 1.5)
+60 -27
Ver Arquivo
@@ -12,7 +12,8 @@
(cross-compile currently only configured/tested on w32ce-arm and
android-arm/-x86)
Use ANT_OPTS=-Dskip-native to skip building native parts.
Use ANT_OPTS=-Dskip-native=false to build native parts, or directly
invoke the native or test targets
Use ANT_OPTS=-Dheadless to run tests headless
Use ANT_OPTS=-Drelease to stage a final, non-snapshot version
-->
@@ -71,16 +72,13 @@
<property name="jni.revision" value="0"/>
<property name="jni.build" value="${build.number}"/>
<property name="jni.version" value="${jni.major}.${jni.minor}.${jni.revision}"/>
<property name="jni.md5" value="059b6e5f0534df9b7f28dd7a87485721"/>
<property name="jni.md5" value="1a6047467b59e8748f975e03016ce3d9"/>
<property name="spec.title" value="Java Native Access (JNA)"/>
<property name="spec.vendor" value="${vendor}"/>
<property name="spec.version" value="${jna.major}"/>
<property name="impl.title" value="com.sun.jna"/>
<property name="impl.vendor" value="${spec.vendor}"/>
<property name="impl.version" value="${jna.version} (b${jna.build})"/>
<condition property="jni.valid" value="true">
<isset property="skip-native"/>
</condition>
<!-- Set up restrictions for w32ce, based on JavaME/CDC -->
<condition property="compatibility" value="1.4">
@@ -114,12 +112,12 @@
<property name="maven-javadoc-jar" value="${dist}/${artifactId}-${jna.version}-javadoc.jar" />
<property name="maven-sources-jar" value="${dist}/${artifactId}-${jna.version}-sources.jar" />
<property name="platform-jar" value="${dist}/platform.jar"/>
<property name="platform-jar" value="${dist}/jna-platform.jar"/>
<property name="platform-javadoc-jar" value="${dist}/platform-${jna.version}-javadoc.jar" />
<property name="platform-sources-jar" value="${dist}/platform-${jna.version}-sources.jar" />
<property name="pom" value="pom-jna.xml" />
<property name="pom-platform" value="pom-platform.xml" />
<property name="pom-platform" value="pom-jna-platform.xml" />
<!-- defined maven snapshots and staging repository id and url -->
<property name="maven-snapshots-repository-id" value="snapshots.java.net" />
@@ -138,6 +136,13 @@
<target name="-dynamic-properties">
<condition property="-native" value="true">
<not><isset property="build-native"/></not>
</condition>
<condition property="jni.valid" value="true">
<isset property="-native"/>
</condition>
<replaceregexp match="(&lt;version&gt;).*(&lt;/version&gt;)"
replace="\1${jna.version}\2"
file="${pom}"/>
@@ -225,12 +230,17 @@
<condition property="os.prefix" value="sunos-${jre.arch}">
<os name="SunOS"/>
</condition>
<condition property="os.prefix" value="bsd-${jre.arch}">
<or>
<os name="FreeBSD"/>
<condition property="os.prefix" value="freebsd-${jre.arch}">
<os name="FreeBSD"/>
</condition>
<condition property="os.prefix" value="openbsd-${jre.arch}">
<os name="OpenBSD"/>
<os name="NetBSD"/>
</or>
</condition>
<condition property="os.prefix" value="netbsd-${jre.arch}">
<os name="NetBSD"/>
</condition>
<condition property="os.prefix" value="kfreebsd-${jre.arch}">
<os name="GNU/kFreeBSD"/>
</condition>
<fail unless="os.prefix" message="OS/arch not supported (${os.name}/${jre.arch}), edit build.xml and native/Makefile to add it."/>
<!-- Keep all natives separate -->
@@ -390,10 +400,14 @@ processor=arm;osname=linux,
com/sun/jna/linux-ia64/libjnidispatch.so;
processor=ia64;osname=linux,
com/sun/jna/bsd-x86/libjnidispatch.so;
processor=x86;osname=openbsd;osname=freebsd;osname=netbsd,
com/sun/jna/bsd-x86-64/libjnidispatch.so;
processor=x86-64;osname=openbsd;osname=freebsd;osname=netbsd,
com/sun/jna/freebsd-x86/libjnidispatch.so;
processor=x86;osname=freebsd,
com/sun/jna/freebsd-x86-64/libjnidispatch.so;
processor=x86-64;osname=freebsd,
com/sun/jna/openbsd-x86/libjnidispatch.so;
processor=x86;osname=openbsd,
com/sun/jna/openbsd-x86-64/libjnidispatch.so;
processor=x86-64;osname=openbsd,
com/sun/jna/darwin/libjnidispatch.jnilib;
osname=macosx;processor=x86;processor=x86-64;processor=ppc
@@ -444,12 +458,18 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
<zipfileset src="${lib.native}/sunos-sparcv9.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/sunos-sparcv9"/>
<zipfileset src="${lib.native}/bsd-x86.jar"
<zipfileset src="${lib.native}/freebsd-x86.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/bsd-x86"/>
<zipfileset src="${lib.native}/bsd-x86-64.jar"
prefix="com/sun/jna/freebsd-x86"/>
<zipfileset src="${lib.native}/freebsd-x86-64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/bsd-x86-64"/>
prefix="com/sun/jna/freebsd-x86-64"/>
<zipfileset src="${lib.native}/openbsd-x86.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/openbsd-x86"/>
<zipfileset src="${lib.native}/openbsd-x86-64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/openbsd-x86-64"/>
<zipfileset src="${lib.native}/win32-x86-64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/win32-x86-64"/>
@@ -486,7 +506,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
</subant>
</target>
<target name="javah" depends="compile" unless="skip-native">
<target name="javah" depends="compile" unless="-native">
<javah classpath="${classes}" destdir="${build.native}" force="yes">
<class name="com.sun.jna.Function"/>
<class name="com.sun.jna.Native"/>
@@ -543,8 +563,10 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/linux-ia64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/linux-ppc.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/linux-ppc64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/bsd-x86.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/bsd-x86-64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/freebsd-x86.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/freebsd-x86-64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/openbsd-x86.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/openbsd-x86-64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/sunos-x86.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/sunos-x86-64.jar" overwrite="true"/>
<copy file="${lib.native}/out-of-date.jar" tofile="${lib.native}/sunos-sparc.jar" overwrite="true"/>
@@ -595,7 +617,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
file="${rsrc}" byline="true"/>
</target>
<target name="native" depends="-setup,javah,-native-api-check,rsrc" unless="skip-native"
<target name="native" depends="-enable-native,-setup,javah,-native-api-check,rsrc" unless="-native"
description="Build native libraries. Use 'ant -DCC=xxx' to build using a compiler other than gcc">
<property name="comment" value="# auto-generated by ant"/>
<replaceregexp match="^JNA_JNI_VERSION=.*"
@@ -750,11 +772,18 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
<src path="${test.src}"/>
<exclude name="${tests.exclude}"/>
</javac>
<!-- Embed testlib-jar at root and at default resource path -->
<mkdir dir="${test.classes}/${os.prefix}"/>
<copy todir="${test.classes}">
<fileset dir="${build.native}">
<include name="*testlib-jar*"/>
</fileset>
</copy>
<copy todir="${test.classes}/${os.prefix}">
<fileset dir="${build.native}">
<include name="*testlib-jar*"/>
</fileset>
</copy>
<!-- Create a jar for easy movement of tests, and jar load test -->
<jar jarfile="${build}/${testjar}">
<fileset dir="${test.classes}">
@@ -764,7 +793,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
</jar>
<!-- Ensure jar-based library is unavailable on FS-based class path -->
<delete>
<fileset dir="${test.classes}">
<fileset dir="${build}">
<include name="**/*testlib-jar*"/>
</fileset>
</delete>
@@ -808,9 +837,13 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
<chmod file="${shared}/*.dll" perm="+x"/>
</target>
<target name="-enable-native" unless="-native">
<property name="build-native" value="true"/>
</target>
<!-- When running tests from an IDE, be sure to set jna.library.path -->
<!-- to where the test library (testlib) is found. -->
<target name="test" depends="jar,compile-tests" unless="cross-compile"
<target name="test" depends="-enable-native,jar,compile-tests" unless="cross-compile"
description="Run all unit tests">
<property name="test.fork" value="yes"/>
<property name="reports.junit" location="${reports}/junit"/>
@@ -960,7 +993,7 @@ osname=macosx;processor=x86;processor=x86-64;processor=ppc
description="Build distribution files">
<copy todir="${dist}">
<fileset dir="${build}" includes="${jar},${minjar}"/>
<fileset dir="${contrib}/platform/dist" includes="platform.jar"/>
<fileset dir="${contrib}/platform/dist" includes="jna-platform.jar"/>
<fileset dir="${lib.native}">
<include name="*.jar"/>
<exclude name="out-of-date.jar"/>
+66 -66
Ver Arquivo
@@ -1,66 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.alphamaskdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.alphamaskdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-alphamask.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.AlphaMaskDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.alphamaskdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.alphamaskdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-alphamask.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.AlphaMaskDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
+68 -68
Ver Arquivo
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.balloonmanagerdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.balloonmanagerdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-balloonmanager.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.BalloonManagerDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.balloonmanagerdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.balloonmanagerdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-balloonmanager.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.BalloonManagerDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
+68 -68
Ver Arquivo
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.balloontipsdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.balloontipsdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-balloontips.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.FilteredTextField" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.balloontipsdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.balloontipsdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-balloontips.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.FilteredTextField" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
+68 -68
Ver Arquivo
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.dnddemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.dnddemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-dnd.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.GhostedDragImageDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.dnddemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.dnddemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-dnd.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.GhostedDragImageDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
+2 -6
Ver Arquivo
@@ -14,17 +14,14 @@ debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/platform.jar
dist.jar=${dist.dir}/jna-platform.jar
dist.javadoc.dir=${dist.dir}/javadoc
file.reference.jna.jar=../../build/jna.jar
file.reference.jna-d64.jar=../../build-d64/jna.jar
file.reference.jna-test.jar=../../build/jna-test.jar
file.reference.jna-test-d64.jar=../../build-d64/jna-test.jar
libs.junit.classpath=../../lib/junit.jar
jar.compress=false
javac.classpath=\
${file.reference.jna.jar}:\
${file.reference.jna-d64.jar}
${file.reference.jna.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
@@ -33,7 +30,6 @@ javac.target=1.5
javac.test.classpath=\
${javac.classpath}:\
${file.reference.jna-test.jar}:\
${file.reference.jna-test-d64.jar}:\
${build.classes.dir}:\
${libs.junit.classpath}
javadoc.additionalparam=
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
@@ -18,6 +18,7 @@ import java.util.ArrayList;
import java.util.List;
import com.sun.jna.LastErrorException;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
@@ -48,7 +49,7 @@ public abstract class Kernel32Util implements WinDef {
/**
* Format a message from the value obtained from {@link
* Kernel32.GetLastError} or {@link Native.getLastError}.
* Kernel32#GetLastError} or {@link Native#getLastError}.
* @param code
* int
* @return
@@ -84,7 +85,7 @@ public abstract class Kernel32Util implements WinDef {
return formatMessage(code.intValue());
}
/** @deprecated use {@link formatMessage(HRESULT)} instead. */
/** @deprecated use {@link #formatMessage(WinNT.HRESULT)} instead. */
public static String formatMessageFromHR(HRESULT code) {
return formatMessage(code.intValue());
}
@@ -305,4 +306,33 @@ public abstract class Kernel32Util implements WinDef {
if (!Kernel32.INSTANCE.WritePrivateProfileString(appName, keyName, string, fileName))
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
/**
* Convenience method to get the processor information. Takes care of auto-growing the array.
*
* @return the array of processor information.
*/
public static final WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] getLogicalProcessorInformation()
{
int sizePerStruct = new WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION().size();
WinDef.DWORDByReference bufferSize = new WinDef.DWORDByReference(new WinDef.DWORD(sizePerStruct));
Memory memory;
while (true)
{
memory = new Memory(bufferSize.getValue().intValue());
if (! Kernel32.INSTANCE.GetLogicalProcessorInformation(memory, bufferSize))
{
int err = Kernel32.INSTANCE.GetLastError();
if (err != WinError.ERROR_INSUFFICIENT_BUFFER)
throw new Win32Exception(err);
}
else
{
break;
}
}
WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION firstInformation = new WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION(memory);
int returnedStructCount = bufferSize.getValue().intValue() / sizePerStruct;
return (WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]) firstInformation.toArray(new WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[returnedStructCount]);
}
}
@@ -16,6 +16,7 @@ import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.INT_PTR;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.PointerByReference;
@@ -168,4 +169,42 @@ public interface Shell32 extends ShellAPI, StdCallLibrary {
* @return {@code true} if successful; otherwise, {@code false}.
*/
boolean SHGetSpecialFolderPath(HWND owner, char[] path, int csidl, boolean create);
/**
* SHAppBarMessage function
*
* @param dwMessage
* Appbar message value to send. This parameter can be one of the following values.
* {@link ShellAPI#ABM_NEW} Registers a new appbar and specifies the message identifier that the system should use to send notification messages to the appbar.
* {@link ShellAPI#ABM_REMOVE} Unregisters an appbar, removing the bar from the system's internal list.
* {@link ShellAPI#ABM_QUERYPOS} Requests a size and screen position for an appbar.
* {@link ShellAPI#ABM_SETPOS} Sets the size and screen position of an appbar.
* {@link ShellAPI#ABM_GETSTATE} Retrieves the autohide and always-on-top states of the Windows taskbar.
* {@link ShellAPI#ABM_GETTASKBARPOS} Retrieves the bounding rectangle of the Windows taskbar. Note that this applies only to the system taskbar. Other objects, particularly toolbars supplied with third-party software, also can be present. As a result, some of the screen area not covered by the Windows taskbar might not be visible to the user. To retrieve the area of the screen not covered by both the taskbar and other app barsÑthe working area available to your applicationÑ, use the GetMonitorInfo function.
* {@link ShellAPI#ABM_ACTIVATE} Notifies the system to activate or deactivate an appbar. The lParam member of the APPBARDATA pointed to by pData is set to TRUE to activate or FALSE to deactivate.
* {@link ShellAPI#ABM_GETAUTOHIDEBAR} Retrieves the handle to the autohide appbar associated with a particular edge of the screen.
* {@link ShellAPI#ABM_SETAUTOHIDEBAR} Registers or unregisters an autohide appbar for an edge of the screen.
* {@link ShellAPI#ABM_WINDOWPOSCHANGED} Notifies the system when an appbar's position has changed.
* {@link ShellAPI#ABM_SETSTATE} Windows XP and later: Sets the state of the appbar's autohide and always-on-top attributes.
*
* @param pData
* A pointer to an APPBARDATA structure. The content of the structure on entry and on exit depends on the value set in the dwMessage parameter. See the individual message pages for specifics.
*
* @return This function returns a message-dependent value. For more information, see the Windows SDK documentation for the specific appbar message sent.
*
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787951(v=vs.85).aspx">ABM_NEW</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787955(v=vs.85).aspx">ABM_REMOVE</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787953(v=vs.85).aspx">ABM_QUERYPOS</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787959(v=vs.85).aspx">ABM_SETPOS</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787947(v=vs.85).aspx">ABM_GETSTATE</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787949(v=vs.85).aspx">ABM_GETTASKBARPOS</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787943(v=vs.85).aspx">ABM_ACTIVATE</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787945(v=vs.85).aspx">ABM_GETAUTOHIDEBAR</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787957(v=vs.85).aspx">ABM_SETAUTOHIDEBAR</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787963(v=vs.85).aspx">ABM_WINDOWPOSCHANGED</a>
* @see <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb787961(v=vs.85).aspx">ABM_SETSTATE</a>
*
*/
UINT_PTR SHAppBarMessage( DWORD dwMessage, APPBARDATA pData );
}
@@ -19,7 +19,13 @@ import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinDef.UINT;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.PSID;
import com.sun.jna.win32.StdCallLibrary;
/**
@@ -115,5 +121,89 @@ public interface ShellAPI extends StdCallLibrary {
}
return encoded + "\0";
}
}
/**
* Appbar message value to send. This parameter can be one of the following
* values.
*/
int ABM_NEW = 0x00000000;
/**
* Registers a new appbar and specifies the message identifier that the
* system should use to send notification messages to the appbar.
*/
int ABM_REMOVE = 0x00000001;
/** Unregisters an appbar, removing the bar from the system's internal list.*/
int ABM_QUERYPOS = 0x00000002;
/** Requests a size and screen position for an appbar. */
int ABM_SETPOS = 0x00000003;
/** Sets the size and screen position of an appbar. */
int ABM_GETSTATE = 0x00000004;
/** Retrieves the autohide and always-on-top states of the Windows taskbar. */
int ABM_GETTASKBARPOS = 0x00000005;
/**
* Retrieves the bounding rectangle of the Windows taskbar. Note that this
* applies only to the system taskbar. Other objects, particularly toolbars
* supplied with third-party software, also can be present. As a result,
* some of the screen area not covered by the Windows taskbar might not be
* visible to the user. To retrieve the area of the screen not covered by
* both the taskbar and other app barsÑthe working area available to your
* applicationÑ, use the GetMonitorInfo function.
*/
int ABM_ACTIVATE = 0x00000006;
/**
* Notifies the system to activate or deactivate an appbar. The lParam
* member of the APPBARDATA pointed to by pData is set to TRUE to activate
* or FALSE to deactivate.
*/
int ABM_GETAUTOHIDEBAR = 0x00000007;
/**
* Retrieves the handle to the autohide appbar associated with a particular
* edge of the screen.
*/
int ABM_SETAUTOHIDEBAR = 0x00000008;
/** Registers or unregisters an autohide appbar for an edge of the screen. */
int ABM_WINDOWPOSCHANGED = 0x00000009;
/** Notifies the system when an appbar's position has changed. */
int ABM_SETSTATE = 0x0000000A;
/** Left edge. */
int ABE_LEFT = 0;
/** Top edge. */
int ABE_TOP = 1;
/** Right edge. */
int ABE_RIGHT = 2;
/** Bottom edge. */
int ABE_BOTTOM = 3;
/**
* Contains information about a system appbar message.
*/
public static class APPBARDATA extends Structure {
public static class ByReference extends APPBARDATA implements Structure.ByReference {
}
public DWORD cbSize;
public HWND hWnd;
public UINT uCallbackMessage;
public UINT uEdge;
public RECT rc;
public LPARAM lParam;
public APPBARDATA() {
super();
}
public APPBARDATA(Pointer p) {
super(p);
}
@Override
protected List getFieldOrder() {
return Arrays.asList("cbSize", "hWnd", "uCallbackMessage", "uEdge", "rc", "lParam");
}
}
}
@@ -429,7 +429,7 @@ public interface WinBase extends StdCallLibrary, WinDef, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" });
}
}
}
/** Unnamed inner union. */
@@ -1,14 +1,14 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32;
@@ -25,12 +25,15 @@ import com.sun.jna.Structure;
import com.sun.jna.Union;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.platform.win32.WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION;
import com.sun.jna.platform.win32.WinNT.LOGICAL_PROCESSOR_RELATIONSHIP;
/**
* This module defines the 32-Bit Windows types and constants that are defined
* by NT, but exposed through the Win32 API. Ported from WinNT.h Microsoft
* Windows SDK 6.0A. Avoid including any NIO Buffer mappings here; put them in a
* DLL-derived interface (e.g. kernel32, user32, etc) instead.
*
*
* @author dblock[at]dblock.org
*/
@SuppressWarnings("serial")
@@ -251,7 +254,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "Luid", "Attributes" });
}
public LUID_AND_ATTRIBUTES() {
}
@@ -266,11 +269,11 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
* and its attributes. SIDs are used to uniquely identify users or groups.
*/
public static class SID_AND_ATTRIBUTES extends Structure {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "Sid", "Attributes" });
}
public SID_AND_ATTRIBUTES() {
super();
}
@@ -296,11 +299,11 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
* (SID) that will be applied to newly created objects.
*/
public static class TOKEN_OWNER extends Structure {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "Owner" });
}
public TOKEN_OWNER() {
super();
}
@@ -324,9 +327,9 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
public static class PSID extends Structure {
public static class ByReference extends PSID implements Structure.ByReference { }
protected List getFieldOrder() {
return Arrays.asList(new String[] { "sid" });
protected List getFieldOrder() {
return Arrays.asList(new String[] { "sid" });
}
public PSID() {
@@ -386,11 +389,11 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
* token.
*/
public static class TOKEN_USER extends Structure {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "User" });
}
public TOKEN_USER() {
super();
}
@@ -417,11 +420,11 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
* identifiers (SIDs) in an access token.
*/
public static class TOKEN_GROUPS extends Structure {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "GroupCount", "Group0" });
}
public TOKEN_GROUPS() {
super();
}
@@ -465,7 +468,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
* contains the LUID and attributes of a privilege.
*/
public LUID_AND_ATTRIBUTES Privileges[];
protected List getFieldOrder() {
return Arrays.asList(new String[] { "PrivilegeCount", "Privileges" });
}
@@ -679,7 +682,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
/**
* The FILE_NOTIFY_INFORMATION structure describes the changes found by the
* ReadDirectoryChangesW function.
*
*
* This structure is non-trivial since it is a pattern stamped into a large
* block of result memory rather than something that stands alone or is used
* for input.
@@ -690,7 +693,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
public int FileNameLength;
// filename is not nul-terminated, so we can't use a String/WString
public char[] FileName = new char[1];
protected List getFieldOrder() {
return Arrays.asList(new String[] { "NextEntryOffset", "Action", "FileNameLength", "FileName" });
}
@@ -946,7 +949,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
int REG_FULL_RESOURCE_DESCRIPTOR = 9;
/**
*
*
*/
int REG_RESOURCE_REQUIREMENTS_LIST = 10;
@@ -994,14 +997,14 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
}
public UNION u;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "u" });
}
/**
* Low DWORD.
*
*
* @return DWORD.
*/
public DWORD getLow() {
@@ -1010,7 +1013,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
/**
* High DWORD.
*
*
* @return DWORD.
*/
public DWORD getHigh() {
@@ -1019,7 +1022,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
/**
* 64-bit value.
*
*
* @return 64-bit value.
*/
public long getValue() {
@@ -1435,72 +1438,72 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
public static final int WinBuiltinTerminalServerLicenseServersSid = 60;
/**
*
*
*/
public static final int WinBuiltinDCOMUsersSid = 61;
/**
*
*
*/
public static final int WinBuiltinIUsersSid = 62;
/**
*
*
*/
public static final int WinIUserSid = 63;
/**
*
*
*/
public static final int WinBuiltinCryptoOperatorsSid = 64;
/**
*
*
*/
public static final int WinUntrustedLabelSid = 65;
/**
*
*
*/
public static final int WinLowLabelSid = 66;
/**
*
*
*/
public static final int WinMediumLabelSid = 67;
/**
*
*
*/
public static final int WinHighLabelSid = 68;
/**
*
*
*/
public static final int WinSystemLabelSid = 69;
/**
*
*
*/
public static final int WinWriteRestrictedCodeSid = 70;
/**
*
*
*/
public static final int WinCreatorOwnerRightsSid = 71;
/**
*
*
*/
public static final int WinCacheablePrincipalsGroupSid = 72;
/**
*
*
*/
public static final int WinNonCacheablePrincipalsGroupSid = 73;
/**
*
*
*/
public static final int WinEnterpriseReadonlyControllersSid = 74;
@@ -1572,7 +1575,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "dwOSVersionInfoSize", "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", "dwPlatformId", "szCSDVersion" });
}
public OSVERSIONINFO() {
szCSDVersion = new char[128];
dwOSVersionInfoSize = new DWORD(size()); // sizeof(OSVERSIONINFO)
@@ -1657,7 +1660,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "dwOSVersionInfoSize", "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", "dwPlatformId", "szCSDVersion", "wServicePackMajor", "wServicePackMinor", "wSuiteMask", "wProductType", "wReserved"});
}
public OSVERSIONINFOEX() {
szCSDVersion = new char[128];
dwOSVersionInfoSize = new DWORD(size()); // sizeof(OSVERSIONINFOEX)
@@ -1862,7 +1865,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "Length", "Reserved", "RecordNumber", "TimeGenerated", "TimeWritten", "EventID", "EventType", "NumStrings", "EventCategory", "ReservedFlags", "ClosingRecordNumber", "StringOffset", "UserSidLength", "UserSidOffset", "DataLength", "DataOffset"});
}
public EVENTLOGRECORD() {
}
@@ -1960,18 +1963,18 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
}
public byte[] data;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "data" });
}
}
public static class ACL extends Structure {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "AclRevision", "Sbz1", "AclSize", "AceCount", "Sbz2" });
}
public ACL() {
}
@@ -2030,7 +2033,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
protected List getFieldOrder() {
return Arrays.asList(new String[] { "Revision", "Sbz1", "Control", "Owner", "Group", "Sacl", "Dacl" });
}
private ACL DACL;
public SECURITY_DESCRIPTOR_RELATIVE() {
@@ -2070,7 +2073,7 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
public ACEStructure(Pointer p) {
super(p);
}
protected List getFieldOrder() {
return Arrays.asList(new String[] { "AceType", "AceFlags", "AceSize" });
}
@@ -2172,4 +2175,218 @@ public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {
void callback(int errorCode, int nBytesTransferred,
WinBase.OVERLAPPED overlapped);
}
/**
* Describes the relationship between the specified processor set. This structure is used with the
* {@link Kernel32#GetLogicalProcessorInformation} function.
*/
public static class SYSTEM_LOGICAL_PROCESSOR_INFORMATION extends Structure {
/**
* The processor mask identifying the processors described by this structure. A processor mask is a bit
* vector in which each set bit represents an active processor in the relationship.
*/
public ULONG_PTR processorMask;
/**
* The relationship between the processors identified by the value of the {@link #processorMask} member.
* This member can be one of
* {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationCache},
* {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationNumaNode},
* {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationProcessorCore} or
* {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationProcessorPackage}.
*
* @see LOGICAL_PROCESSOR_RELATIONSHIP
*/
public int /* LOGICAL_PROCESSOR_RELATIONSHIP */ relationship;
/**
* A union of fields which differs depending on {@link #relationship}.
*/
public AnonymousUnionPayload payload;
public SYSTEM_LOGICAL_PROCESSOR_INFORMATION() {
}
public SYSTEM_LOGICAL_PROCESSOR_INFORMATION(Pointer memory) {
super(memory);
read();
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "processorMask", "relationship", "payload" });
}
public static class AnonymousUnionPayload extends Union {
/**
* Contains valid data only if {@link #relationship} is {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationProcessorCore}.
*/
public AnonymousStructProcessorCore processorCore;
/**
* Contains valid data only if {@link #relationship} is {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationNumaNode}.
*/
public AnonymousStructNumaNode numaNode;
/**
* <p>Identifies the characteristics of a particular cache. There is one record returned for each cache
* reported. Some or all caches may not be reported, depending on how caches are identified. Therefore,
* do not assume the absence of any particular caches. Caches are not necessarily shared among
* logical processors.</p>
*
* <p>Contains valid data only if {@link #relationship} is
* {@link LOGICAL_PROCESSOR_RELATIONSHIP#RelationCache}.</p>
*
* <p>This member was not supported until Windows Server 2003 SP1 / Windows XP Professional x64.</p>
*/
public CACHE_DESCRIPTOR cache;
/**
* Reserved. Do not use.
*/
public ULONGLONG[] reserved = new ULONGLONG[2];
}
public static class AnonymousStructProcessorCore extends Structure {
/**
* <p>If the value of this mmeber is {@code 1}, the logical processors identified by the value of the
* {@link #processorMask} member share functional units, as in Hyperthreading or SMT. Otherwise, the
* identified logical processors do not share functional units.</p>
*
* <p>Note: Prior to Windows Vista, this member is also {@code 1} for cores that share a physical
* package.</p>
*/
public BYTE flags;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "flags" });
}
}
public static class AnonymousStructNumaNode extends Structure {
/**
* Identifies the NUMA node. Valid values are {@code 0} to the highest NUMA node number inclusive.
* A non-NUMA multiprocessor system will report that all processors belong to one NUMA node.
*/
public DWORD nodeNumber;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "nodeNumber" });
}
}
}
/**
* Represents the relationship between the processor set identified in the corresponding
* {@link SYSTEM_LOGICAL_PROCESSOR_INFORMATION} or <code>SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX</code> structure.
*/
public interface LOGICAL_PROCESSOR_RELATIONSHIP {
/**
* The specified logical processors share a single processor core.
*/
int RelationProcessorCore = 0;
/**
* The specified logical processors are part of the same NUMA node.
*/
int RelationNumaNode = 1;
/**
* <p>The specified logical processors share a cache.</p>
*
* <p>Not supported until Windows Server 2003 SP1 / Windows XP Professional x64.</p>
*/
int RelationCache = 2;
/**
* <p>The specified logical processors share a physical package (a single package socketed or soldered onto a
* motherboard may contain multiple processor cores or threads, each of which is treated as a separate
* processor by the operating system.)</p>
*
* <p>Not supported until Windows Server 2003 SP1 / Windows XP Professional x64.</p>
*/
int RelationProcessorPackage = 3;
/**
* <p>The specified logical processors share a single processor group.</p>
*
* <p>Not supported until Windows Server 2008 R2.</p>
*/
int RelationGroup = 4;
/**
* <p>On input, retrieves information about all possible relation types. This value is not used on output.</p>
*
* <p>Not supported until Windows Server 2008 R2.</p>
*/
int RelationAll = 0xFFFF;
}
byte CACHE_FULLY_ASSOCIATIVE = (byte)0xFF;
/**
* Describes the cache attributes.
*/
public static class CACHE_DESCRIPTOR extends Structure {
/**
* The cache level. This member can be 1, 2 or 3, corresponding to L1, L2 or L3 cache, respectively (other
* values may be supported in the future.)
*/
public BYTE level;
/**
* The cache associativity. If this member is {@link #CACHE_FULLY_ASSOCIATIVE}, the cache is fully
* associative.
*/
public BYTE associativity;
/**
* The cache line size, in bytes.
*/
public WORD lineSize;
/**
* The cache size, in bytes.
*/
public DWORD size;
/**
* The cache type.
*
* @see PROCESSOR_CACHE_TYPE
*/
public int /* PROCESSOR_CACHE_TYPE */ type;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "level", "associativity", "lineSize", "size", "type" });
}
}
/**
* Represents the type of processor cache identifier in the corresponding {@link CACHE_DESCRIPTOR} structure.
*/
public static abstract class PROCESSOR_CACHE_TYPE {
/**
* The cache is unified.
*/
public static int CacheUnified = 0;
/**
* The cache is for processor instructions.
*/
public static int CacheInstruction = 1;
/**
* The cache is for data.
*/
public static int CacheData = 2;
/**
* The cache is for traces.
*/
public static int CacheTrace = 3;
}
}
@@ -23,6 +23,7 @@ import java.io.PrintWriter;
import junit.framework.TestCase;
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
import com.sun.jna.platform.win32.WinNT.LOGICAL_PROCESSOR_RELATIONSHIP;
/**
* @author dblock[at]dblock[dot]org
@@ -180,4 +181,13 @@ public class Kernel32UtilTest extends TestCase {
assertEquals(reader.readLine(), null);
reader.close();
}
public final void testGetLogicalProcessorInformation() {
WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] informationArray = Kernel32Util.getLogicalProcessorInformation();
assertTrue(informationArray.length >= 1); // docs say so
for (WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION info : informationArray) {
assertTrue(info.processorMask.intValue() >= 0);
assertTrue(info.relationship >= LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore && info.relationship <= LOGICAL_PROCESSOR_RELATIONSHIP.RelationAll);
}
}
}
@@ -15,14 +15,22 @@ package com.sun.jna.platform.win32;
import junit.framework.TestCase;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.ShellAPI.APPBARDATA;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.ptr.PointerByReference;
/**
* @author dblock[at]dblock[dot]org
* @author markus[at]headcrashing[dot]eu
*/
public class Shell32Test extends TestCase {
private static final int RESIZE_HEIGHT = 500;
private static final int WM_USER = 0x0400;
public static void main(String[] args) {
junit.textui.TestRunner.run(Shell32Test.class);
}
@@ -48,4 +56,75 @@ public class Shell32Test extends TestCase {
assertTrue(Shell32.INSTANCE.SHGetSpecialFolderPath(null, pszPath, ShlObj.CSIDL_APPDATA, false));
assertFalse(Native.toString(pszPath).isEmpty());
}
private void newAppBar() {
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
data.uCallbackMessage.setValue(WM_USER + 1);
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_NEW), data);
assertNotNull(result);
}
private void removeAppBar() {
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_REMOVE), data);
assertNotNull(result);
}
private void queryPos(APPBARDATA data) {
UINT_PTR h = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_QUERYPOS), data);
assertNotNull(h);
assertTrue(h.intValue() > 0);
}
public void testResizeDesktopFromBottom() throws InterruptedException {
newAppBar();
APPBARDATA data = new APPBARDATA.ByReference();
data.uEdge.setValue(ShellAPI.ABE_BOTTOM);
data.rc.top = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN) - RESIZE_HEIGHT;
data.rc.left = 0;
data.rc.bottom = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN);
data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN);
queryPos(data);
UINT_PTR h = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_SETPOS), data);
assertNotNull(h);
assertTrue(h.intValue() >= 0);
removeAppBar();
}
public void testResizeDesktopFromTop() throws InterruptedException {
newAppBar();
APPBARDATA data = new APPBARDATA.ByReference();
data.uEdge.setValue(ShellAPI.ABE_TOP);
data.rc.top = 0;
data.rc.left = 0;
data.rc.bottom = RESIZE_HEIGHT;
data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN);
queryPos(data);
UINT_PTR h = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_SETPOS), data);
assertNotNull(h);
assertTrue(h.intValue() >= 0);
removeAppBar();
}
}
+68 -68
Ver Arquivo
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.shapedwindowdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.shapedwindowdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-shapedwindow.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.ShapedWindowDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.shapedwindowdemo" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.shapedwindowdemo.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-shapedwindow.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.ShapedWindowDemo" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes/com"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
+68 -68
Ver Arquivo
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.w32keyhook" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.w32keyhook.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-w32keyhook.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.KeyHook" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes" />
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}" />
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.w32keyhook" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.w32keyhook.</description>
<!-- Locations -->
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-w32keyhook.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.contrib.demo.KeyHook" />
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run Demo. -->
<target name="run" depends="compile">
<java classname="${main-class}" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}/com">
<fileset dir="${src}/com">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes" />
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}" />
</jar>
</target>
</project>
+77 -77
Ver Arquivo
@@ -1,77 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.x11" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.x11.</description>
<!-- Locations -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="jna-src" location="../../src"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-x11.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="platform.jar"/>
</path>
<!-- Run XDesktopDemo. -->
<target name="runXDesktopDemo" depends="compile">
<java classname="jnacontrib.x11.demos.XDesktopDemo" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Run XTestDemo. -->
<target name="runXTestDemo" depends="compile">
<java classname="jnacontrib.x11.demos.XTestDemo" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}">
<fileset dir="${src}">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="jnacontrib.x11.demos.XDesktopDemo"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project name="jnacontrib.x11" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.x11.</description>
<!-- Locations -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="jna-src" location="../../src"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-x11.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
<fileset dir="../platform/dist" includes="jna-platform.jar"/>
</path>
<!-- Run XDesktopDemo. -->
<target name="runXDesktopDemo" depends="compile">
<java classname="jnacontrib.x11.demos.XDesktopDemo" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Run XTestDemo. -->
<target name="runXTestDemo" depends="compile">
<java classname="jnacontrib.x11.demos.XTestDemo" fork="true">
<classpath>
<pathelement location="${classes}" />
<path refid="classpath"/>
</classpath>
</java>
</target>
<!-- Delete class and jar files. -->
<target name="clean">
<delete dir="${classes}"/>
<delete file="${jar}"/>
<delete dir="${build}"/>
</target>
<!-- Compile all classes. -->
<target name="compile">
<mkdir dir="${classes}"/>
<!-- Compile the project. -->
<javac srcdir="${src}" destdir="${classes}" target="1.5" source="1.5"
encoding="UTF-8" debug="on" includeantruntime="false">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Create jar-file. -->
<target name="jar" depends="compile">
<!-- Copy all non-java files to classes. -->
<copy todir="${classes}">
<fileset dir="${src}">
<exclude name="**/*.java"/>
</fileset>
</copy>
<jar jarfile="${jar}" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="jnacontrib.x11.demos.XDesktopDemo"/>
</manifest>
<!-- platform -->
<fileset dir="../platform/build/classes"/>
<!-- jna -->
<zipfileset src="${file.reference.jna.jar}"/>
</jar>
</target>
</project>
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
+5 -5
Ver Arquivo
@@ -1,5 +1,5 @@
qRNQnmsMoNMDGXUenVfHVPuFPrNBGUUdBvfgtIdgVQWSbAa
mj2KW7Oo9ud83ZbEKfK2xx922L04T>gYjDdLjGld4Wa6MPW
NrqPtxROppqOmmqROMPSTnMmRqNOMnMnoPVSXswPsVXQwXV
SPVVUtUNQmnmqmUUnopmqsvommmmmUUnopmqsvommmmmUUg
kXkabskgXsXkkbqUUnmm
onoMnApeShTpQtDJbcUgJTIFONPQeUndIgfQWWNNddIwBl
mi2Kp5RjfhIJdGCSo<bOTNof2KNxm9KCi5lxEyKI9BJW3p
qOPQUXpopOopMMPqnPnXXQPNOPNRnqQNQqStwVxuQSTtVW
UrwSUSSSTVwxWSXNmrrpnmqmUUnpsvpntsmmmmmUUnpsvp
ntsmmmmmUUFmbkWJlroZbW4bsbilmjbkqUUnmmmm
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
+37 -13
Ver Arquivo
@@ -48,7 +48,7 @@ OS=$(shell uname | sed -e 's/CYGWIN.*/win32/g' \
-e 's/Linux.*/linux/g')
JNA_JNI_VERSION=4.0.0 # auto-generated by ant
CHECKSUM=059b6e5f0534df9b7f28dd7a87485721 # auto-generated by ant
CHECKSUM=1a6047467b59e8748f975e03016ce3d9 # auto-generated by ant
JAVA_INCLUDES=-I"$(JAVA_HOME)/include" \
-I"$(JAVA_HOME)/include/$(OS)"
@@ -162,8 +162,22 @@ endif
ifeq ($(OS),win32)
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
CDEFINES=-DHAVE_PROTECTION -DPSAPI_VERSION=1 -DFFI_BUILDING
ifeq ($(ARCH),amd64)
# To build entirely with mingw64, comment out this line (default is MSVC)
USE_MSVC=true
else
# To build 32-bit under MSVC, un-comment this line (default is gcc)
#USE_MSVC=true
endif
CDEFINES=-DHAVE_PROTECTION -DPSAPI_VERSION=1 -DFFI_BUILDING -DUNICODE -D_UNICODE
ifndef USE_MSVC
LIBS=-lpsapi
else
ARSFX=.lib
COPT=
LIBS=psapi.lib
endif
WINDRES=windres
EXTRAOBJS=$(RSRC)
STRIP=@echo
@@ -172,6 +186,14 @@ LIBSFX=.dll
TESTLIB_TRUNC=$(BUILD)/testlib-truncated.dll
ifneq ($(ARCH),amd64)
ifdef USE_MSVC
CC=$(FFI_SRC)/../cc.sh -m32
CPP=$(FFI_SRC)/../cc.sh -m32 -E
LD=$(FFI_SRC)/../ld.sh -m32
FFI_CONFIG+= && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
FFI_ENV+=LD="$(LD)" CPP="$(CPP)"
endif
ifeq ($(CC),gcc)
# -mno-cygwin is only available on GCC 3; GCC 4 requires an explicit mingw
# installation
@@ -187,18 +209,19 @@ endif
else
# Set CC to $(MINGW) to enable mingw64 cross compiler; ensure $(MINGW) is in
# Undefine USE_MSVC to enable mingw64 cross compiler; ensure $(MINGW) is in
# PATH. Should build properly as of 111121, but lacks SEH, so MSVC build is
# preferred
MINGW_PREFIX?=x86_64-w64-mingw32-
MINGW=$(MINGW_PREFIX)gcc
# Still need windres from mingw distribution
# Still need windres from mingw distribution, even if building with MSVC
WINDRES=$(MINGW_PREFIX)windres
# To build entirely with mingw64, uncomment this line
#CC=$(MINGW)
ifndef USE_MSVC
CC=$(MINGW)
endif
ifeq ($(CC),$(MINGW))
# No SEH under mingw64
# No SEH under mingw64, thus no HAVE_PROTECTION
CDEFINES=-DPSAPI_VERSION=1
LD = $(CC)
LDFLAGS=-o $@ -shared
@@ -209,9 +232,6 @@ else
CC=$(FFI_SRC)/../cc.sh -m64
CPP=$(FFI_SRC)/../cc.sh -m64 -E
LD=$(FFI_SRC)/../ld.sh -m64
COPT=
LIBS=psapi.lib
ARSFX=.lib
FFI_CONFIG+=--host=x86_64-w64-mingw32 && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
FFI_ENV+=LD="$(LD)" CPP="$(CPP)"
EXTRAOBJS+=$(DLLCB)
@@ -231,7 +251,7 @@ ARCH=$(shell uname -m | sed 's/i.86/i386/g')
PCFLAGS+=-fPIC
CINCLUDES+=-I/usr/X11R6/include
LDFLAGS=-o $@ -shared
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT -DUSE_DEAFULT_LIBNAME_ENCODING
endif
ifeq ($(OS),solaris)
@@ -239,7 +259,7 @@ ifeq ($(ARCH),)
ARCH=$(shell uname -p)
endif
PCFLAGS+=-fPIC
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT -DUSE_DEFAULT_LIBNAME_ENCODING
ifeq ($(ARCH), sparcv9)
# alter CC instead of PCFLAGS, since we need to pass it down to libffi
# configure and some of the other settings in PCFLAGS might make the build
@@ -253,7 +273,7 @@ endif
ifeq ($(OS),aix)
LIBSFX=.a
PCFLAGS+=-fPIC
CDEFINES+=-DHAVE_PROTECTION -DNO_JAWT -Wall -D_AIX -DPOWERPC_AIX
CDEFINES+=-DHAVE_PROTECTION -DNO_JAWT -Wall -D_AIX -DPOWERPC_AIX -D_THREAD_SAFE_ERRNO
COPT+=-D_AIX -DPOWERPC_AIX -mxl-compat
LDFLAGS+=-Wl,-lc128,-lc,-lm,-lpthread
FFI_ENV+=AR_FLAGS="-X32_64 cru"
@@ -288,6 +308,10 @@ ifeq ($(ARCH),ppc)
LD += -m32
HOST_CONFIG=--host=ppc-linux
endif
ifeq ($(ARCH),i386)
CC += -m32
LD += -m32
endif
endif
endif
+118 -86
Ver Arquivo
@@ -23,12 +23,17 @@
# include <windows.h>
# define TLS_SET(KEY,VALUE) TlsSetValue(KEY,VALUE)
# define TLS_GET(KEY) TlsGetValue(KEY)
# define TLS_KEY_T DWORD
#else
# include <sys/types.h>
# include <sys/param.h>
# include <pthread.h>
# define PTHREADS
# define TLS_SET(KEY,VALUE) (pthread_setspecific(KEY,VALUE)==0)
# define TLS_GET(KEY) pthread_getspecific(KEY)
# define TLS_KEY_T pthread_key_t
#endif
#include "dispatch.h"
#ifdef __cplusplus
@@ -49,10 +54,9 @@ extern "C" {
#endif
#else /* _WIN64 */
#ifdef _MSC_VER
// FIXME is "PROC NEAR" correct?
#define ASMFN(X) extern void asmfn ## X(); \
__asm asmfn ## X PROC NEAR \
__asm jmp fn[X]
#define ASMFN(X) void __declspec(naked) asmfn ## X () { \
__asm jmp DWORD PTR fn[4*X] \
}
#else
#define ASMFN(X) extern void asmfn ## X (); asm(".globl _asmfn" #X "\n\
_asmfn" #X ":\n\
@@ -74,9 +78,21 @@ static void * const dll_fptrs[] = {
#endif /* _WIN32 && !_WIN32_WCE */
typedef struct _tls {
JavaVM* jvm;
jint last_error;
// Contents set to JNI_TRUE if thread has terminated and detached properly
int* termination_flag;
jboolean jvm_thread;
jboolean detach;
char name[256];
} thread_storage;
static void callback_dispatch(ffi_cif*, void*, void**, void*);
static jclass classObject;
extern void println(JNIEnv*, const char*);
callback*
create_callback(JNIEnv* env, jobject obj, jobject method,
jobjectArray param_types, jclass return_type,
@@ -92,7 +108,7 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
jsize argc;
JavaVM* vm;
int rtype;
char msg[64];
char msg[MSG_SIZE];
int i;
int cvt = 0;
const char* throw_type = NULL;
@@ -165,8 +181,9 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
}
}
// Java callback method is called using varargs, so promote floats to
// double where appropriate for the platform
if (cb->arg_types[i]->type == FFI_TYPE_FLOAT) {
// Java method is varargs, so promote floats to double
cb->java_arg_types[i+3] = &ffi_type_double;
cb->conversion_flags[i] = CVT_FLOAT;
cvt = 1;
@@ -236,7 +253,7 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
case 'D': cb->fptr_offset = OFFSETOF(env, CallDoubleMethod); break;
default: cb->fptr_offset = OFFSETOF(env, CallObjectMethod); break;
}
status = ffi_prep_cif(&cb->java_cif, java_abi, argc+3, java_ffi_rtype, cb->java_arg_types);
status = ffi_prep_cif_var(&cb->java_cif, java_abi, 2, argc+3, java_ffi_rtype, cb->java_arg_types);
if (!ffi_error(env, "callback setup (2)", status)) {
ffi_prep_closure_loc(cb->closure, &cb->cif, callback_dispatch, cb,
cb->x_closure);
@@ -478,43 +495,72 @@ callback_invoke(JNIEnv* env, callback *cb, ffi_cif* cif, void *resp, void **cbar
}
}
// Handle automatic thread cleanup
static void detach_thread(void* data) {
if (data != NULL) {
JavaVM* jvm = (JavaVM *)data;
(*jvm)->DetachCurrentThread(jvm);
static TLS_KEY_T tls_thread_data_key;
static thread_storage* get_thread_storage(JNIEnv* env) {
thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key);
if (tls == NULL) {
tls = (thread_storage*)malloc(sizeof(thread_storage));
if (!tls) {
throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage");
}
else {
snprintf(tls->name, sizeof(tls->name), "<uninitialized thread name>");
tls->jvm_thread = JNI_TRUE;
tls->last_error = 0;
tls->termination_flag = NULL;
if ((*env)->GetJavaVM(env, &tls->jvm) != JNI_OK) {
free(tls);
throwByName(env, EIllegalState, "JNA: Could not get JavaVM");
tls = NULL;
}
else if (!TLS_SET(tls_thread_data_key, tls)) {
free(tls);
throwByName(env, EOutOfMemory, "JNA: Internal TLS error");
tls = NULL;
}
}
}
return tls;
}
static void dispose_thread_data(void* data) {
thread_storage* tls = (thread_storage*)data;
JavaVM* jvm = tls->jvm;
JNIEnv* env;
int is_attached = (*jvm)->GetEnv(jvm, (void*)&env, JNI_VERSION_1_4) == JNI_OK;
jboolean detached = JNI_TRUE;
if (is_attached) {
if ((*jvm)->DetachCurrentThread(jvm) != 0) {
fprintf(stderr, "JNA: could not detach native thread (automatic)\n");
detached = JNI_FALSE;
}
}
if (tls->termination_flag && detached) {
*(tls->termination_flag) = JNI_TRUE;
}
free(data);
}
#ifdef _WIN32
static DWORD tls_thread_cleanup_key;
static DWORD tls_errno_key, tls_detach_key;
BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
tls_thread_cleanup_key = TlsAlloc();
if (tls_thread_cleanup_key == TLS_OUT_OF_INDEXES) {
return FALSE;
}
tls_detach_key = TlsAlloc();
if (tls_detach_key == TLS_OUT_OF_INDEXES) {
return FALSE;
}
tls_errno_key = TlsAlloc();
if (tls_errno_key == TLS_OUT_OF_INDEXES) {
tls_thread_data_key = TlsAlloc();
if (tls_thread_data_key == TLS_OUT_OF_INDEXES) {
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
TlsFree(tls_thread_cleanup_key);
TlsFree(tls_detach_key);
TlsFree(tls_errno_key);
TlsFree(tls_thread_data_key);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH: {
detach_thread(TlsGetValue(tls_thread_cleanup_key));
thread_storage* tls = (thread_storage*)TlsGetValue(tls_thread_data_key);
if (tls) {
dispose_thread_data(tls);
}
break;
}
default:
@@ -523,71 +569,54 @@ BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD fdwReason, LPVOID lpvReserved) {
return TRUE;
}
#else
#endif
#include <pthread.h>
static pthread_key_t tls_thread_cleanup_key, tls_detach_key;
static void make_thread_cleanup_key() {
pthread_key_create(&tls_thread_cleanup_key, detach_thread);
#ifdef PTHREADS
static void make_thread_data_key() {
pthread_key_create(&tls_thread_data_key, dispose_thread_data);
}
static pthread_key_t tls_errno_key;
static void make_thread_keys() {
pthread_key_create(&tls_errno_key, NULL);
pthread_key_create(&tls_detach_key, NULL);
}
#endif
/** Store the requested detach state for the current thread. */
void
JNA_detach(jboolean d) {
if (!TLS_SET(tls_detach_key, L2A((jlong)(d?THREAD_DETACH:THREAD_LEAVE_ATTACHED)))) {
fprintf(stderr, "JNA: unable to set thread-local detach value\n");
JNA_detach(JNIEnv* env, jboolean detach, void* termination_flag) {
thread_storage* tls = get_thread_storage(env);
if (tls) {
tls->detach = detach;
tls->termination_flag = (int *)termination_flag;
if (detach && tls->jvm_thread) {
throwByName(env, EIllegalState, "Can not detach from a JVM thread");
}
}
}
/** Store the value of errno/GetLastError in TLS */
void
JNA_set_last_error(int err) {
if (!TLS_SET(tls_errno_key, L2A((jlong)err))) {
fprintf(stderr, "JNA: unable to set thread-local errno value\n");
JNA_set_last_error(JNIEnv* env, int err) {
thread_storage* tls = get_thread_storage(env);
if (tls) {
tls->last_error = err;
}
}
/** Store the value of errno/GetLastError in TLS */
int
JNA_get_last_error() {
return (int)A2L(TLS_GET(tls_errno_key));
}
/** Set up to detach the thread when it exits, or clear any handlers if the
argument is NULL.
*/
static void
jvm_detach_on_exit(JavaVM* jvm) {
#ifdef _WIN32
if (!TlsSetValue(tls_thread_cleanup_key, (void *)jvm)) {
fprintf(stderr, "JNA: unable to set thread-local JVM value\n");
JNA_get_last_error(JNIEnv* env) {
thread_storage* tls = get_thread_storage(env);
if (tls) {
return tls->last_error;
}
#else
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
pthread_once(&key_once, make_thread_cleanup_key);
if (!jvm || pthread_getspecific(tls_thread_cleanup_key) == NULL) {
if (pthread_setspecific(tls_thread_cleanup_key, jvm)) {
fprintf(stderr, "JNA: unable to set thread-local JVM value\n");
}
}
#endif
return 0;
}
static void
callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
callback* cb = ((callback *)user_data);
JavaVM* jvm = cb->vm;
JNIEnv* env;
JNIEnv* env = NULL;
int was_attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
jboolean detach = was_attached ? JNI_FALSE : JNI_TRUE;
thread_storage* tls = was_attached ? get_thread_storage(env) : NULL;
if (!was_attached) {
int attach_status = 0;
@@ -613,6 +642,12 @@ callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
else {
attach_status = (*jvm)->AttachCurrentThread(jvm, (void *)&env, &args);
}
tls = get_thread_storage(env);
if (tls) {
snprintf(tls->name, sizeof(tls->name), "%s", args.name ? args.name : "<unconfigured native thread>");
tls->detach = detach;
tls->jvm_thread = JNI_FALSE;
}
// Dispose of allocated memory
free(args.name);
if (attach_status != JNI_OK) {
@@ -623,37 +658,36 @@ callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
(*env)->DeleteWeakGlobalRef(env, args.group);
}
}
if (!tls) {
fprintf(stderr, "JNA: couldn't obtain thread-local storage\n");
return;
}
// Give the callback glue its own local frame to ensure all local references
// are properly disposed
if ((*env)->PushLocalFrame(env, 16) < 0) {
fprintf(stderr, "JNA: Out of memory: Can't allocate local frame\n");
}
else {
TLS_SET(tls_detach_key, L2A((jlong)THREAD_NOCHANGE));
callback_invoke(env, cb, cif, resp, cbargs);
switch((int)A2L(TLS_GET(tls_detach_key))) {
case THREAD_LEAVE_ATTACHED: detach = JNI_FALSE; break;
case THREAD_DETACH: detach = JNI_TRUE; break;
default: break; /* use default detach behavior */
}
// Make note of whether the callback wants to avoid detach
detach = tls->detach && !tls->jvm_thread;
(*env)->PopLocalFrame(env, NULL);
}
if (detach) {
(*jvm)->DetachCurrentThread(jvm);
jvm_detach_on_exit(NULL);
}
else if (!was_attached) {
jvm_detach_on_exit(jvm);
if ((*jvm)->DetachCurrentThread(jvm) != 0) {
fprintf(stderr, "JNA: could not detach thread\n");
}
}
}
const char*
JNA_callback_init(JNIEnv* env) {
#ifndef _WIN32
#ifdef PTHREADS
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
pthread_once(&key_once, make_thread_keys);
pthread_once(&key_once, make_thread_data_key);
#endif
if (!LOAD_CREF(env, Object, "java/lang/Object")) return "java.lang.Object";
@@ -667,10 +701,8 @@ JNA_callback_dispose(JNIEnv* env) {
(*env)->DeleteWeakGlobalRef(env, classObject);
classObject = NULL;
}
#ifndef _WIN32
pthread_key_delete(tls_errno_key);
pthread_key_delete(tls_thread_cleanup_key);
pthread_key_delete(tls_detach_key);
#ifdef PTHREADS
pthread_key_delete(tls_thread_data_key);
#endif
}
+2 -2
Ver Arquivo
@@ -36,7 +36,7 @@ do
shift 1
;;
-m32)
if echo $PATH | grep amd64 >& /dev/null; then
if type cl | grep amd64 >& /dev/null; then
echo "Wrong CL.EXE in path; use 32-bit version"
exit 1
fi
@@ -48,7 +48,7 @@ do
shift 1
;;
-m64)
if ! echo $PATH | grep amd64 >& /dev/null; then
if ! type cl | grep amd64 >& /dev/null; then
echo "Wrong CL.EXE in path; use 64-bit version"
exit 1
fi
+245 -172
Ver Arquivo
@@ -17,14 +17,11 @@
*/
#if defined(_WIN32)
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <psapi.h>
#define STRTYPE wchar_t*
#define NAME2CSTR(ENV,JSTR) newWideCString(ENV,JSTR)
#define NAME2CSTR(ENV,JSTR) w32_short_name(ENV,JSTR)
#ifdef _WIN32_WCE
#include <tlhelp32.h>
#define DEFAULT_LOAD_OPTS 0 /* altered search path unsupported on CE */
@@ -49,7 +46,11 @@
#include <dlfcn.h>
#include <errno.h>
#define STRTYPE char*
#ifdef USE_DEFAULT_LIBNAME_ENCODING
#define NAME2CSTR(ENV,JSTR) newCString(ENV,JSTR)
#else
#define NAME2CSTR(ENV,JSTR) newCStringUTF8(ENV,JSTR)
#endif
#define DEFAULT_LOAD_OPTS (RTLD_LAZY|RTLD_GLOBAL)
#define LOAD_LIBRARY(NAME,OPTS) dlopen(NAME, OPTS)
#define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF)
@@ -80,15 +81,6 @@
#include <jawt_md.h>
#endif
/* Native memory fault protection */
#ifdef HAVE_PROTECTION
#define PROTECT is_protected()
#endif
#include "protect.h"
#define ON_ERROR() throwByName(env, EError, "Invalid memory access")
#define PSTART() PROTECTED_START()
#define PEND() PROTECTED_END(ON_ERROR())
#ifdef HAVE_PROTECTION
// When we have SEH, default to protection on
#if defined(_WIN32) && !(defined(_WIN64) && defined(__GNUC__))
@@ -106,76 +98,11 @@ static int _protect;
extern "C" {
#endif
#ifdef _WIN32
static char*
w32_format_error(int error, char* buf, int len) {
wchar_t* wbuf = NULL;
int wlen =
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, error, 0, (LPWSTR)&wbuf, 0, NULL);
if (wlen > 0) {
WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen+1, buf, len, NULL, NULL);
}
else {
*buf = 0;
}
if (wbuf) {
LocalFree(wbuf);
}
return buf;
}
static HANDLE
w32_find_entry(JNIEnv* env, HANDLE handle, const char* funname) {
void* func = NULL;
if (handle != GetModuleHandle(NULL)) {
func = GetProcAddress(handle, funname);
}
else {
#if defined(_WIN32_WCE)
/* CE has no EnumProcessModules, have to use an alternate API */
HANDLE snapshot;
if ((snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0)) != INVALID_HANDLE_VALUE) {
MODULEENTRY32 moduleInfo;
moduleInfo.dwSize = sizeof(moduleInfo);
if (Module32First(snapshot, &moduleInfo)) {
do {
if ((func = (void *) GetProcAddress(moduleInfo.hModule, funname))) {
break;
}
} while (Module32Next(snapshot, &moduleInfo));
}
CloseToolhelp32Snapshot(snapshot);
}
#else
HANDLE cur_proc = GetCurrentProcess ();
HMODULE *modules;
DWORD needed, i;
if (!EnumProcessModules (cur_proc, NULL, 0, &needed)) {
fail:
throwByName(env, EError, "Unexpected error enumerating modules");
return 0;
}
modules = (HMODULE*) alloca (needed);
if (!EnumProcessModules (cur_proc, modules, needed, &needed)) {
goto fail;
}
for (i = 0; i < needed / sizeof (HMODULE); i++) {
if ((func = (void *) GetProcAddress (modules[i], funname))) {
break;
}
}
#endif
}
return func;
}
#endif
#define MEMCPY(D,S,L) do { \
PSTART(); memcpy(D,S,L); PEND(); \
#define MEMCPY(ENV,D,S,L) do { \
PSTART(); memcpy(D,S,L); PEND(ENV); \
} while(0)
#define MEMSET(D,C,L) do { \
PSTART(); memset(D,C,L); PEND(); \
#define MEMSET(ENV,D,C,L) do { \
PSTART(); memset(D,C,L); PEND(ENV); \
} while(0)
#define MASK_CC com_sun_jna_Function_MASK_CC
@@ -286,6 +213,8 @@ static jfieldID FID_Structure_typeInfo;
static jfieldID FID_IntegerType_value;
static jfieldID FID_PointerType_pointer;
jstring fileEncoding;
/* Forward declarations */
static char* newCString(JNIEnv *env, jstring jstr);
static char* newCStringEncoding(JNIEnv *env, jstring jstr, const char* encoding);
@@ -300,15 +229,139 @@ static ffi_type* getStructureType(JNIEnv *, jobject);
typedef void (JNICALL* release_t)(JNIEnv*,jarray,void*,jint);
#ifdef _WIN32
static char*
w32_format_error(int err, char* buf, int len) {
wchar_t* wbuf = NULL;
int wlen =
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_IGNORE_INSERTS
|FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, err, 0, (LPWSTR)&wbuf, 0, NULL);
if (wlen > 0) {
int result = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, len, NULL, NULL);
if (result == 0) {
fprintf(stderr, "JNA: error converting error message: %d\n", (int)GET_LAST_ERROR());
*buf = 0;
}
else {
buf[len-1] = 0;
}
}
else {
// Error retrieving message
*buf = 0;
}
if (wbuf) {
LocalFree(wbuf);
}
return buf;
}
static wchar_t*
w32_short_name(JNIEnv* env, jstring str) {
wchar_t* wstr = newWideCString(env, str);
if (wstr && *wstr) {
DWORD required;
size_t size = wcslen(wstr) + 5;
wchar_t* prefixed = (wchar_t*)alloca(sizeof(wchar_t) * size);
#ifdef _MSC_VER
swprintf(prefixed, size, L"\\\\?\\%ls", wstr);
#else
swprintf(prefixed, L"\\\\?\\%ls", wstr);
#endif
if ((required = GetShortPathNameW(prefixed, NULL, 0)) != 0) {
wchar_t* wshort = (wchar_t*)malloc(sizeof(wchar_t) * required);
if (GetShortPathNameW(prefixed, wshort, required)) {
free((void *)wstr);
wstr = wshort;
}
else {
char buf[MSG_SIZE];
throwByName(env, EError, LOAD_ERROR(buf, sizeof(buf)));
free((void *)wstr);
free((void *)wshort);
wstr = NULL;
}
}
else if (GET_LAST_ERROR() != ERROR_FILE_NOT_FOUND) {
char buf[MSG_SIZE];
throwByName(env, EError, LOAD_ERROR(buf, sizeof(buf)));
free((void *)wstr);
wstr = NULL;
}
}
return wstr;
}
static HANDLE
w32_find_entry(JNIEnv* env, HANDLE handle, const char* funname) {
void* func = NULL;
if (handle != GetModuleHandle(NULL)) {
func = GetProcAddress(handle, funname);
}
else {
#if defined(_WIN32_WCE)
/* CE has no EnumProcessModules, have to use an alternate API */
HANDLE snapshot;
if ((snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0)) != INVALID_HANDLE_VALUE) {
MODULEENTRY32 moduleInfo;
moduleInfo.dwSize = sizeof(moduleInfo);
if (Module32First(snapshot, &moduleInfo)) {
do {
if ((func = (void *) GetProcAddress(moduleInfo.hModule, funname))) {
break;
}
} while (Module32Next(snapshot, &moduleInfo));
}
CloseToolhelp32Snapshot(snapshot);
}
#else
HANDLE cur_proc = GetCurrentProcess ();
HMODULE *modules;
DWORD needed, i;
if (!EnumProcessModules (cur_proc, NULL, 0, &needed)) {
fail:
throwByName(env, EError, "Unexpected error enumerating modules");
return 0;
}
modules = (HMODULE*) alloca (needed);
if (!EnumProcessModules (cur_proc, modules, needed, &needed)) {
goto fail;
}
for (i = 0; i < needed / sizeof (HMODULE); i++) {
if ((func = (void *) GetProcAddress (modules[i], funname))) {
break;
}
}
#endif
}
return func;
}
#endif /* _WIN32 */
#if 0
/** Invokes System.err.println (for debugging only). */
static void
void
println(JNIEnv* env, const char* msg) {
jclass cls = (*env)->FindClass(env, "java/lang/System");
if (!cls) {
fprintf(stderr, "JNA: failed to find java.lang.System\n");
return;
}
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "err",
"Ljava/io/PrintStream;");
"Ljava/io/PrintStream;");
jobject err = (*env)->GetStaticObjectField(env, cls, fid);
if (!err) {
fprintf(stderr, "JNA: failed to find System.err\n");
return;
}
jclass pscls = (*env)->FindClass(env, "java/io/PrintStream");
if (!pscls) {
fprintf(stderr, "JNA: failed to find java.io.PrintStream\n");
return;
}
jmethodID mid = (*env)->GetMethodID(env, pscls, "println",
"(Ljava/lang/String;)V");
jstring str = newJavaString(env, msg, CHARSET_UTF8);
@@ -337,7 +390,7 @@ throwByName(JNIEnv *env, const char *name, const char *msg)
/** Translate FFI errors into exceptions. */
jboolean
ffi_error(JNIEnv* env, const char* op, ffi_status status) {
char msg[256];
char msg[MSG_SIZE];
switch(status) {
case FFI_BAD_ABI:
snprintf(msg, sizeof(msg), "%s: Invalid calling convention", op);
@@ -376,7 +429,7 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray arr,
void** ffi_values;
ffi_abi abi;
ffi_status status;
char msg[128];
char msg[MSG_SIZE];
callconv_t callconv = flags & MASK_CC;
const char* volatile throw_type = NULL;
const char* volatile throw_msg = NULL;
@@ -553,20 +606,20 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray arr,
status = ffi_prep_cif(&cif, abi, nargs, ffi_return_type, ffi_types);
if (!ffi_error(env, "Native call setup", status)) {
PSTART();
if (flags & THROW_LAST_ERROR) {
if ((flags & THROW_LAST_ERROR) != 0) {
SET_LAST_ERROR(0);
}
ffi_call(&cif, FFI_FN(func), resP, ffi_values);
if (flags & THROW_LAST_ERROR) {
int error = GET_LAST_ERROR();
if (error) {
char emsg[1024];
snprintf(msg, sizeof(msg), "[%d] %s", error, STR_ERROR(error, emsg, sizeof(emsg)));
{
int err = GET_LAST_ERROR();
JNA_set_last_error(env, err);
if ((flags & THROW_LAST_ERROR) && err) {
char emsg[MSG_SIZE];
snprintf(msg, sizeof(msg), "[%d] %s", err, STR_ERROR(err, emsg, sizeof(emsg)));
throw_type = ELastError;
throw_msg = msg;
}
}
JNA_set_last_error(GET_LAST_ERROR());
PROTECTED_END(do { throw_type=EError;throw_msg="Invalid memory access";} while(0));
}
@@ -605,6 +658,8 @@ getChars(JNIEnv* env, wchar_t* volatile dst, jcharArray chars, volatile jint off
int i;
(*env)->GetCharArrayRegion(env, chars, off, count, buf);
for (i=0;i < count;i++) {
// TODO: ensure proper encoding conversion from jchar to native
// wchar_t
dst[i] = (wchar_t)buf[i];
}
dst += count;
@@ -614,7 +669,7 @@ getChars(JNIEnv* env, wchar_t* volatile dst, jcharArray chars, volatile jint off
}
}
}
PEND();
PEND(env);
}
static void
@@ -644,7 +699,7 @@ setChars(JNIEnv* env, wchar_t* src, jcharArray chars, volatile jint off, volatil
}
}
}
PEND();
PEND(env);
}
/* Translates a Java string to a C string using the
@@ -709,13 +764,16 @@ newCStringEncoding(JNIEnv *env, jstring jstr, const char* encoding)
/* Translates a Java string to a wide C string using the String.toCharArray
* method.
*/
// TODO: are any encoding changes required?
static wchar_t *
newWideCString(JNIEnv *env, jstring str)
{
jcharArray chars = 0;
wchar_t *result = NULL;
if ((*env)->IsSameObject(env, str, NULL)) {
return result;
}
chars = (*env)->CallObjectMethod(env, str, MID_String_toCharArray);
if (!(*env)->ExceptionCheck(env)) {
jint len = (*env)->GetArrayLength(env, chars);
@@ -725,7 +783,6 @@ newWideCString(JNIEnv *env, jstring str)
throwByName(env, EOutOfMemory, "Can't allocate wide C string");
return NULL;
}
// TODO: ensure proper encoding conversion from jchar to native wchar_t
getChars(env, result, chars, 0, len);
if ((*env)->ExceptionCheck(env)) {
free((void *)result);
@@ -812,7 +869,7 @@ newJavaString(JNIEnv *env, const char *ptr, const char* charset)
}
}
}
PEND();
PEND(env);
return result;
}
@@ -1005,10 +1062,13 @@ initializeThread(callback* cb, AttachOptions* args) {
JavaVM* jvm = cb->vm;
JNIEnv* env;
jobject group = NULL;
int attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
if ((*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL) != JNI_OK) {
fprintf(stderr, "JNA: Can't attach native thread to VM for callback thread initialization\n");
return NULL;
if (!attached) {
if ((*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL) != JNI_OK) {
fprintf(stderr, "JNA: Can't attach native thread to VM for callback thread initialization\n");
return NULL;
}
}
(*env)->PushLocalFrame(env, 16);
{
@@ -1029,7 +1089,11 @@ initializeThread(callback* cb, AttachOptions* args) {
}
}
(*env)->PopLocalFrame(env, NULL);
(*jvm)->DetachCurrentThread(jvm);
if (!attached) {
if ((*jvm)->DetachCurrentThread(jvm) != 0) {
fprintf(stderr, "JNA: could not detach thread after callback init\n");
}
}
return group;
}
@@ -1055,7 +1119,7 @@ toNative(JNIEnv* env, jobject obj, void* valuep, size_t size, jboolean promote)
}
}
else {
MEMSET(valuep, 0, size);
MEMSET(env, valuep, 0, size);
}
}
@@ -1068,7 +1132,7 @@ toNativeTypeMapped(JNIEnv* env, jobject obj, void* valuep, size_t size, jobject
}
}
else {
MEMSET(valuep, 0, size);
MEMSET(env, valuep, 0, size);
}
}
@@ -1224,22 +1288,15 @@ getBufferArray(JNIEnv* env, jobject buf,
}
#endif /* NO_NIO_BUFFERS */
static const void*
get_system_property(JNIEnv* env, const char* name, jboolean wide) {
static jstring
get_system_property(JNIEnv* env, const char* name) {
jclass classSystem = (*env)->FindClass(env, "java/lang/System");
if (classSystem != NULL) {
jmethodID mid = (*env)->GetStaticMethodID(env, classSystem, "getProperty",
"(Ljava/lang/String;)Ljava/lang/String;");
if (mid != NULL) {
jstring propname = newJavaString(env, name, CHARSET_UTF8);
jstring value = (*env)->CallStaticObjectMethod(env, classSystem,
mid, propname);
if (value) {
if (wide) {
return newWideCString(env, value);
}
return newCStringUTF8(env, value);
}
return (*env)->CallStaticObjectMethod(env, classSystem, mid, propname);
}
}
return NULL;
@@ -1374,6 +1431,11 @@ JNA_init(JNIEnv* env) {
if (!LOAD_FID(env, FID_Double_value, classDouble, "value", "D"))
return "Double.value";
fileEncoding = get_system_property(env, "file.encoding");
if (fileEncoding) {
fileEncoding = (*env)->NewGlobalRef(env, fileEncoding);
}
return NULL;
}
@@ -1591,7 +1653,7 @@ method_handler(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) {
void* oldresp = resp;
const char* volatile throw_type = NULL;
const char* volatile throw_msg = NULL;
char msg[64];
char msg[MSG_SIZE];
if (data->flags) {
objects = alloca(data->cif.nargs * sizeof(void*));
@@ -1729,17 +1791,16 @@ method_handler(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) {
SET_LAST_ERROR(0);
}
ffi_call(&data->cif, FFI_FN(data->fptr), resp, args);
if (data->throw_last_error) {
int error = GET_LAST_ERROR();
if (error) {
char emsg[1024];
snprintf(msg, sizeof(msg), "[%d]%s", error, STR_ERROR(error, emsg, sizeof(emsg)));
{
int err = GET_LAST_ERROR();
JNA_set_last_error(env, err);
if (data->throw_last_error && err) {
char emsg[MSG_SIZE];
snprintf(msg, sizeof(msg), "[%d] %s", err, STR_ERROR(err, emsg, sizeof(emsg)));
throw_type = ELastError;
throw_msg = msg;
}
}
JNA_set_last_error(GET_LAST_ERROR());
PROTECTED_END(do { throw_type=EError;throw_msg="Invalid memory access"; } while(0));
}
@@ -1796,8 +1857,9 @@ method_handler(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) {
case CVT_ARRAY_LONG:
case CVT_ARRAY_FLOAT:
case CVT_ARRAY_DOUBLE:
if (*(void **)args[i] && release[i])
if (*(void **)args[i] && release[i] != NULL) {
release[i](env, objects[i], elems[i], 0);
}
break;
}
}
@@ -1815,9 +1877,8 @@ closure_handler(ffi_cif* cif, void* resp, void** argp, void *cdata)
JavaVM* jvm = cb->vm;
JNIEnv* env;
jobject obj;
int attached;
int attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
if (!attached) {
if ((*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL) != JNI_OK) {
fprintf(stderr, "JNA: Can't attach native thread to VM for closure handler\n");
@@ -1846,7 +1907,9 @@ closure_handler(ffi_cif* cif, void* resp, void** argp, void *cdata)
}
if (!attached) {
(*jvm)->DetachCurrentThread(jvm);
if ((*jvm)->DetachCurrentThread(jvm) != 0) {
fprintf(stderr, "JNA: could not detach thread after callback handling\n");
}
}
}
@@ -2015,7 +2078,7 @@ Java_com_sun_jna_Native_open(JNIEnv *env, jclass UNUSED(cls), jstring lib, jint
handle = (void *)LOAD_LIBRARY(libname, flags != -1 ? flags : DEFAULT_LOAD_OPTS);
if (!handle) {
char buf[1024];
char buf[MSG_SIZE];
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(buf, sizeof(buf)));
}
if (libname != NULL) {
@@ -2033,7 +2096,7 @@ JNIEXPORT void JNICALL
Java_com_sun_jna_Native_close(JNIEnv *env, jclass UNUSED(cls), jlong handle)
{
if (FREE_LIBRARY(L2A(handle))) {
char buf[1024];
char buf[MSG_SIZE];
throwByName(env, EError, LOAD_ERROR(buf, sizeof(buf)));
}
}
@@ -2054,7 +2117,7 @@ Java_com_sun_jna_Native_findSymbol(JNIEnv *env, jclass UNUSED(cls),
if (funname != NULL) {
func = (void *)FIND_ENTRY(handle, funname);
if (!func) {
char buf[1024];
char buf[MSG_SIZE];
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(buf, sizeof(buf)));
}
free((void *)funname);
@@ -2072,7 +2135,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3BII
{
PSTART();
(*env)->GetByteArrayRegion(env, arr, off, n, L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2096,7 +2159,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3DII
{
PSTART();
(*env)->GetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2109,7 +2172,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3FII
{
PSTART();
(*env)->GetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2122,7 +2185,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3III
{
PSTART();
(*env)->GetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2135,7 +2198,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3JII
{
PSTART();
(*env)->GetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2148,7 +2211,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3SII
{
PSTART();
(*env)->GetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2168,7 +2231,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_indexOf__JB
result = i;
++i;
}
PEND();
PEND(env);
return result;
}
@@ -2183,7 +2246,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3BII
{
PSTART();
(*env)->SetByteArrayRegion(env, arr, off, n, L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2207,7 +2270,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3DII
{
PSTART();
(*env)->SetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2220,7 +2283,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3FII
{
PSTART();
(*env)->SetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2233,7 +2296,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3III
{
PSTART();
(*env)->SetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2246,7 +2309,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3JII
{
PSTART();
(*env)->SetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2259,7 +2322,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3SII
{
PSTART();
(*env)->SetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr));
PEND();
PEND(env);
}
/*
@@ -2271,7 +2334,7 @@ JNIEXPORT jbyte JNICALL Java_com_sun_jna_Native_getByte
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jbyte res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2284,7 +2347,7 @@ JNIEXPORT jchar JNICALL Java_com_sun_jna_Native_getChar
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
wchar_t res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return (jchar)res;
}
@@ -2297,7 +2360,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native__1getPointer
(JNIEnv *env, jclass UNUSED(cls), jlong addr)
{
void *ptr = NULL;
MEMCPY(&ptr, L2A(addr), sizeof(ptr));
MEMCPY(env, &ptr, L2A(addr), sizeof(ptr));
return A2L(ptr);
}
@@ -2325,7 +2388,7 @@ JNIEXPORT jdouble JNICALL Java_com_sun_jna_Native_getDouble
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jdouble res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2338,7 +2401,7 @@ JNIEXPORT jfloat JNICALL Java_com_sun_jna_Native_getFloat
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jfloat res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2351,7 +2414,7 @@ JNIEXPORT jint JNICALL Java_com_sun_jna_Native_getInt
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jint res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2364,7 +2427,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_getLong
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jlong res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2377,7 +2440,7 @@ JNIEXPORT jshort JNICALL Java_com_sun_jna_Native_getShort
(JNIEnv * env, jclass UNUSED(cls), jlong addr)
{
jshort res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
MEMCPY(env, &res, L2A(addr), sizeof(res));
return res;
}
@@ -2412,7 +2475,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_sun_jna_Native_getStringBytes
throwByName(env, EOutOfMemory, "Can't allocate byte array");
}
}
PEND();
PEND(env);
return bytes;
}
@@ -2424,7 +2487,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_sun_jna_Native_getStringBytes
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setMemory
(JNIEnv *env, jclass UNUSED(cls), jlong addr, jlong count, jbyte value)
{
MEMSET(L2A(addr), (int)value, (size_t)count);
MEMSET(env, L2A(addr), (int)value, (size_t)count);
}
/*
@@ -2435,7 +2498,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setMemory
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setByte
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jbyte value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2447,7 +2510,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setChar
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jchar value)
{
wchar_t ch = value;
MEMCPY(L2A(addr), &ch, sizeof(ch));
MEMCPY(env, L2A(addr), &ch, sizeof(ch));
}
/*
@@ -2459,7 +2522,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setPointer
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jlong value)
{
void *ptr = L2A(value);
MEMCPY(L2A(addr), &ptr, sizeof(void *));
MEMCPY(env, L2A(addr), &ptr, sizeof(void *));
}
/*
@@ -2470,7 +2533,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setPointer
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setDouble
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jdouble value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2481,7 +2544,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setDouble
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setFloat
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jfloat value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2492,7 +2555,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setFloat
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setInt
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jint value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2503,7 +2566,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setInt
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setLong
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jlong value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2514,7 +2577,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setLong
JNIEXPORT void JNICALL Java_com_sun_jna_Native_setShort
(JNIEnv * env, jclass UNUSED(cls), jlong addr, jshort value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
MEMCPY(env, L2A(addr), &value, sizeof(value));
}
/*
@@ -2531,7 +2594,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setWideString
str = newWideCString(env, value);
if (str != NULL) {
MEMCPY(L2A(addr), str, size);
MEMCPY(env, L2A(addr), str, size);
free((void*)str);
}
}
@@ -2574,7 +2637,7 @@ Java_com_sun_jna_Native_sizeof(JNIEnv *env, jclass UNUSED(cls), jint type)
case com_sun_jna_Native_TYPE_SIZE_T: return sizeof(size_t);
default:
{
char msg[1024];
char msg[MSG_SIZE];
snprintf(msg, sizeof(msg), "Invalid sizeof type %d", (int)type);
throwByName(env, EIllegalArgument, msg);
return -1;
@@ -2827,8 +2890,9 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass UNUSED(classp), job
// Use Unicode strings in case the path to the library includes non-ASCII
// characters.
wchar_t* path = L"jawt.dll";
wchar_t* prop = (wchar_t*)get_system_property(env, "java.home", JNI_TRUE);
if (prop != NULL) {
jstring jprop = get_system_property(env, "java.home");
if (jprop != NULL) {
const wchar_t* prop = newWideCString(env, jprop);
const wchar_t* suffix = L"/bin/jawt.dll";
size_t len = wcslen(prop) + wcslen(suffix) + 1;
path = (wchar_t*)alloca(len * sizeof(wchar_t));
@@ -2843,12 +2907,12 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass UNUSED(classp), job
#define JAWT_NAME path
#endif
if ((jawt_handle = LOAD_LIBRARY(JAWT_NAME, DEFAULT_LOAD_OPTS)) == NULL) {
char msg[1024];
char msg[MSG_SIZE];
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(msg, sizeof(msg)));
return -1;
}
if ((pJAWT_GetAWT = (void*)FIND_ENTRY(jawt_handle, METHOD_NAME)) == NULL) {
char msg[1024], buf[1024];
char msg[MSG_SIZE], buf[MSG_SIZE];
snprintf(msg, sizeof(msg), "Error looking up JAWT method %s: %s",
METHOD_NAME, LOAD_ERROR(buf, sizeof(buf)));
throwByName(env, EUnsatisfiedLink, msg);
@@ -2967,13 +3031,13 @@ Java_com_sun_jna_Native_isProtected(JNIEnv *UNUSED(env), jclass UNUSED(classp))
JNIEXPORT void JNICALL
Java_com_sun_jna_Native_setLastError(JNIEnv *env, jclass UNUSED(classp), jint code) {
JNA_set_last_error(code);
JNA_set_last_error(env, code);
SET_LAST_ERROR(code);
}
JNIEXPORT jint JNICALL
Java_com_sun_jna_Native_getLastError(JNIEnv *env, jclass UNUSED(classp)) {
return JNA_get_last_error();
return JNA_get_last_error(env);
}
JNIEXPORT jstring JNICALL
@@ -3015,7 +3079,9 @@ JNI_OnLoad(JavaVM *jvm, void *UNUSED(reserved)) {
result = 0;
}
if (!attached) {
(*jvm)->DetachCurrentThread(jvm);
if ((*jvm)->DetachCurrentThread(jvm) != 0) {
fprintf(stderr, "JNA: could not detach thread on initial load\n");
}
}
return result;
@@ -3055,6 +3121,11 @@ JNI_OnUnload(JavaVM *vm, void *UNUSED(reserved)) {
}
}
if (fileEncoding) {
(*env)->DeleteGlobalRef(env, fileEncoding);
fileEncoding = NULL;
}
for (i=0;i < sizeof(refs)/sizeof(refs[0]);i++) {
if (*refs[i]) {
(*env)->DeleteWeakGlobalRef(env, *refs[i]);
@@ -3073,7 +3144,9 @@ JNI_OnUnload(JavaVM *vm, void *UNUSED(reserved)) {
#endif
if (!attached) {
(*vm)->DetachCurrentThread(vm);
if ((*vm)->DetachCurrentThread(vm) != 0) {
fprintf(stderr, "JNA: could not detach thread on unload\n");
}
}
}
@@ -3275,8 +3348,8 @@ Java_com_sun_jna_Native_initialize_1ffi_1type(JNIEnv *env, jclass UNUSED(cls), j
}
JNIEXPORT void JNICALL
Java_com_sun_jna_Native_detach(JNIEnv* env, jclass UNUSED(cls), jboolean d) {
JNA_detach(d);
Java_com_sun_jna_Native_setDetachState(JNIEnv* env, jclass UNUSED(cls), jboolean d, jlong flag) {
JNA_detach(env, d, L2A(flag));
}
#ifdef __cplusplus
+13 -13
Ver Arquivo
@@ -13,10 +13,12 @@
#ifndef DISPATCH_H
#define DISPATCH_H
#define MSG_SIZE 1024
#include "ffi.h"
#include "com_sun_jna_Function.h"
#include "com_sun_jna_Native.h"
#if defined(sun) || defined(_AIX)
#if defined(__sun__) || defined(_AIX)
# include <alloca.h>
#endif
#ifdef _WIN32
@@ -94,10 +96,6 @@ enum {
/* callback behavior flags */
enum {
CB_HAS_INITIALIZER = com_sun_jna_Native_CB_HAS_INITIALIZER,
// detach options
THREAD_NOCHANGE,
THREAD_DETACH,
THREAD_LEAVE_ATTACHED,
};
typedef struct _callback {
@@ -134,12 +132,14 @@ typedef struct _callback {
#endif
#if defined(_MSC_VER)
#include "snprintf.h"
#define strdup _strdup
#if defined(_WIN64)
#define L2A(X) ((void *)(X))
#define A2L(X) ((jlong)(X))
#define snprintf sprintf_s
#else
#if defined(_WIN32_WCE)
#define snprintf _snprintf
#define L2A(X) ((void *)(unsigned long)(X))
#define A2L(X) ((jlong)(unsigned long)(X))
#endif
#endif
@@ -177,10 +177,10 @@ extern int get_jtype(JNIEnv*, jclass);
extern ffi_type* get_ffi_type(JNIEnv*, jclass, char);
extern ffi_type* get_ffi_rtype(JNIEnv*, jclass, char);
extern const char* JNA_callback_init(JNIEnv*);
extern void JNA_set_last_error(int);
extern int JNA_get_last_error();
extern void JNA_set_last_error(JNIEnv*,int);
extern int JNA_get_last_error(JNIEnv*);
extern void JNA_callback_dispose(JNIEnv*);
extern void JNA_detach(jboolean);
extern void JNA_detach(JNIEnv*,jboolean,void*);
extern callback* create_callback(JNIEnv*, jobject, jobject,
jobjectArray, jclass,
callconv_t, jint, jstring);
@@ -225,9 +225,9 @@ extern jobject initializeThread(callback*,AttachOptions*);
#define PROTECT is_protected()
#endif
#include "protect.h"
#define ON_ERROR() throwByName(env, EError, "Invalid memory access")
#define ON_ERROR(ENV) throwByName(ENV, EError, "Invalid memory access")
#define PSTART() PROTECTED_START()
#define PEND() PROTECTED_END(ON_ERROR())
#define PEND(ENV) PROTECTED_END(ON_ERROR(ENV))
#ifdef __cplusplus
}
+2 -2
Ver Arquivo
@@ -15,7 +15,7 @@ do
case $1
in
-m32)
if echo $PATH | grep amd64; then
if type link | grep amd64; then
echo "Wrong LINK.EXE in path; use 32-bit version"
exit 1
fi
@@ -26,7 +26,7 @@ do
shift 1
;;
-m64)
if ! echo $PATH | grep amd64; then
if ! type link | grep amd64; then
echo "Wrong LINK.EXE in path; use 64-bit version"
exit 1
fi
+13
Ver Arquivo
@@ -0,0 +1,13 @@
#ifndef _SNPRINTF_H
#define _SNPRINTF_H
// snprintf on windows is broken; always nul-terminate manually
// DO NOT rely on the return value...
static int snprintf(char * str, size_t size, const char * format, ...) {
int retval;
va_list ap;
va_start(ap, format);
retval = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
va_end(ap);
return retval;
}
#endif /* _SNPRINTF_H */
+16 -7
Ver Arquivo
@@ -19,6 +19,7 @@ extern "C" {
#include <wchar.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#if !defined(_WIN32_WCE)
#include <errno.h>
#endif
@@ -28,6 +29,7 @@ typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef __int64 int64_t;
#include "snprintf.h"
#else
#include <stdint.h>
#endif
@@ -45,7 +47,11 @@ typedef __int64 int64_t;
#define THREAD_EXIT() ExitThread(0)
#define THREAD_FUNC(FN,ARG) DWORD WINAPI FN(LPVOID ARG)
#define THREAD_CURRENT() GetCurrentThreadId()
#ifdef _WIN64
#define THREAD_RETURN
#else
#define THREAD_RETURN return 0
#endif
#else
#define EXPORT
#include <unistd.h>
@@ -635,9 +641,9 @@ typedef struct thread_data {
int repeat_count;
int sleep_time;
void (*func)(void);
char name[256];
} thread_data;
static THREAD_FUNC(thread_function, arg) {
// make a local copy
thread_data td = *(thread_data*)arg;
void (*func)(void) = td.func;
int i;
@@ -646,18 +652,21 @@ static THREAD_FUNC(thread_function, arg) {
func();
SLEEP(td.sleep_time);
}
free((void*)arg);
THREAD_EXIT();
THREAD_RETURN;
}
static thread_data data;
EXPORT void
callVoidCallbackThreaded(void (*func)(void), int n, int ms) {
callVoidCallbackThreaded(void (*func)(void), int n, int ms, const char* name) {
THREAD_T thread;
data.repeat_count = n;
data.sleep_time = ms;
data.func = func;
THREAD_CREATE(&thread, &thread_function, &data);
thread_data* data = (thread_data*)malloc(sizeof(thread_data));
data->repeat_count = n;
data->sleep_time = ms;
data->func = func;
snprintf(data->name, sizeof(data->name), "%s", name);
THREAD_CREATE(&thread, &thread_function, data);
}
EXPORT int
+53 -53
Ver Arquivo
@@ -1,53 +1,53 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.java.dev.jna</groupId>
<artifactId>platform</artifactId>
<version>4.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java Native Access Platform</name>
<description>Java Native Access Platform</description>
<url>https://github.com/twall/jna</url>
<licenses>
<license>
<name>LGPL, version 2.1</name>
<url>http://www.gnu.org/licenses/licenses.html</url>
<distribution>repo</distribution>
</license>
<license>
<name>ASL, version 2</name>
<url>http://www.apache.org/licenses/</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/twall/jna</connection>
<developerConnection>scm:git:ssh://git@github.com/twall/jna.git</developerConnection>
<url>https://github.com/twall/jna</url>
</scm>
<developers>
<developer>
<id>twall</id>
<name>Timothy Wall</name>
<roles>
<role>Owner</role>
</roles>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java Native Access Platform</name>
<description>Java Native Access Platform</description>
<url>https://github.com/twall/jna</url>
<licenses>
<license>
<name>LGPL, version 2.1</name>
<url>http://www.gnu.org/licenses/licenses.html</url>
<distribution>repo</distribution>
</license>
<license>
<name>ASL, version 2</name>
<url>http://www.apache.org/licenses/</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/twall/jna</connection>
<developerConnection>scm:git:ssh://git@github.com/twall/jna.git</developerConnection>
<url>https://github.com/twall/jna</url>
</scm>
<developers>
<developer>
<id>twall</id>
<name>Timothy Wall</name>
<roles>
<role>Owner</role>
</roles>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
+44 -44
Ver Arquivo
@@ -1,45 +1,45 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java Native Access</name>
<description>Java Native Access</description>
<url>https://github.com/twall/jna</url>
<licenses>
<license>
<name>LGPL, version 2.1</name>
<url>http://www.gnu.org/licenses/licenses.html</url>
<distribution>repo</distribution>
</license>
<license>
<name>ASL, version 2</name>
<url>http://www.apache.org/licenses/</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/twall/jna</connection>
<developerConnection>scm:git:ssh://git@github.com/twall/jna.git</developerConnection>
<url>https://github.com/twall/jna</url>
</scm>
<developers>
<developer>
<id>twall</id>
<name>Timothy Wall</name>
<roles>
<role>Owner</role>
</roles>
</developer>
</developers>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java Native Access</name>
<description>Java Native Access</description>
<url>https://github.com/twall/jna</url>
<licenses>
<license>
<name>LGPL, version 2.1</name>
<url>http://www.gnu.org/licenses/licenses.html</url>
<distribution>repo</distribution>
</license>
<license>
<name>ASL, version 2</name>
<url>http://www.apache.org/licenses/</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/twall/jna</connection>
<developerConnection>scm:git:ssh://git@github.com/twall/jna.git</developerConnection>
<url>https://github.com/twall/jna</url>
</scm>
<developers>
<developer>
<id>twall</id>
<name>Timothy Wall</name>
<roles>
<role>Owner</role>
</roles>
</developer>
</developers>
</project>
+28 -15
Ver Arquivo
@@ -1,4 +1,4 @@
/* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved
/* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -12,12 +12,14 @@
*/
package com.sun.jna;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -36,7 +38,9 @@ class CallbackReference extends WeakReference {
static final Map callbackMap = new WeakHashMap();
static final Map directCallbackMap = new WeakHashMap();
static final Map pointerCallbackMap = new WeakHashMap();
static final Map allocations = new WeakHashMap();
private static final Method PROXY_CALLBACK_METHOD;
static {
@@ -67,16 +71,17 @@ class CallbackReference extends WeakReference {
// Thread name must be UTF8-encoded
{ setStringEncoding("utf8"); }
protected List getFieldOrder() {
return Arrays.asList(new String[] { "daemon", "detach", "name" });
return Arrays.asList(new String[] { "daemon", "detach", "name", });
}
}
/** Called from native code to initialize a callback thread. */
private static ThreadGroup initializeThread(Callback cb, AttachOptions args) {
CallbackThreadInitializer init = null;
if (cb instanceof DefaultCallbackProxy) {
cb = ((DefaultCallbackProxy)cb).getCallback();
}
synchronized(initializers) {
synchronized(callbackMap) {
init = (CallbackThreadInitializer)initializers.get(cb);
}
ThreadGroup group = null;
@@ -92,7 +97,10 @@ class CallbackReference extends WeakReference {
/** Return a Callback associated with the given function pointer.
* If the pointer refers to a Java callback trampoline, return the original
* Java Callback. Otherwise, return a proxy to the native function pointer.
* Java Callback. Otherwise, return a proxy to the native function
* pointer.
* @throws IllegalStateException if the given pointer has already been
* mapped to a callback of a different type.
*/
public static Callback getCallback(Class type, Pointer p) {
return getCallback(type, p, false);
@@ -107,29 +115,30 @@ class CallbackReference extends WeakReference {
throw new IllegalArgumentException("Callback type must be an interface");
Map map = direct ? directCallbackMap : callbackMap;
synchronized(callbackMap) {
for (Iterator i=map.keySet().iterator();i.hasNext();) {
Callback cb = (Callback)i.next();
if (type.isAssignableFrom(cb.getClass())) {
CallbackReference cbref = (CallbackReference)map.get(cb);
Pointer cbp = cbref != null
? cbref.getTrampoline() : getNativeFunctionPointer(cb);
if (p.equals(cbp)) {
return cb;
}
Callback cb = null;
Reference ref = (Reference)pointerCallbackMap.get(p);
if (ref != null) {
cb = (Callback)ref.get();
if (cb != null && !type.isAssignableFrom(cb.getClass())) {
throw new IllegalStateException("Pointer " + p + " already mapped to " + cb);
}
return cb;
}
int ctype = AltCallingConvention.class.isAssignableFrom(type)
? Function.ALT_CONVENTION : Function.C_CONVENTION;
Map foptions = new HashMap(Native.getLibraryOptions(type));
foptions.put(Function.OPTION_INVOKING_METHOD, getCallbackMethod(type));
NativeFunctionHandler h = new NativeFunctionHandler(p, ctype, foptions);
Callback cb = (Callback)Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, h);
cb = (Callback)Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, h);
// No CallbackReference for this callback
map.put(cb, null);
pointerCallbackMap.put(p, new WeakReference(cb));
return cb;
}
}
Pointer cbstruct;
Pointer trampoline;
// Keep a reference to the proxy to avoid premature GC of it
CallbackProxy proxy;
Method method;
@@ -328,7 +337,10 @@ class CallbackReference extends WeakReference {
/** Obtain a pointer to the native glue code for this callback. */
public Pointer getTrampoline() {
return cbstruct.getPointer(0);
if (trampoline == null) {
trampoline = cbstruct.getPointer(0);
}
return trampoline;
}
/** Free native resources associated with this callback when GC'd. */
@@ -386,6 +398,7 @@ class CallbackReference extends WeakReference {
if (cbref == null) {
cbref = new CallbackReference(cb, callingConvention, direct);
map.put(cb, cbref);
pointerCallbackMap.put(cbref.getTrampoline(), new WeakReference(cb));
if (initializers.containsKey(cb)) {
cbref.setCallbackOptions(Native.CB_HAS_INITIALIZER);
}
+28 -2
Ver Arquivo
@@ -286,10 +286,16 @@ public class Function extends Pointer {
TypeMapper mapper =
(TypeMapper)options.get(Library.OPTION_TYPE_MAPPER);
Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD);
Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null;
boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS));
for (int i=0; i < args.length; i++) {
Class paramType = invokingMethod != null
? (isVarArgs(invokingMethod) && i >= paramTypes.length-1
? paramTypes[paramTypes.length-1].getComponentType()
: paramTypes[i])
: null;
args[i] = convertArgument(args, i, invokingMethod,
mapper, allowObjects);
mapper, allowObjects, paramType);
}
Class nativeType = returnType;
@@ -467,7 +473,7 @@ public class Function extends Pointer {
private Object convertArgument(Object[] args, int index,
Method invokingMethod, TypeMapper mapper,
boolean allowObjects) {
boolean allowObjects, Class expectedType) {
Object arg = args[index];
if (arg != null) {
Class type = arg.getClass();
@@ -556,9 +562,29 @@ public class Function extends Pointer {
return new NativeMappedArray((NativeMapped[])arg);
}
else if (Structure[].class.isAssignableFrom(argClass)) {
// If the signature is Structure[], disallow
// Structure.ByReference[] and Structure.ByReference elements
Structure[] ss = (Structure[])arg;
Class type = argClass.getComponentType();
boolean byRef = Structure.ByReference.class.isAssignableFrom(type);
if (expectedType != null) {
if (!Structure.ByReference[].class.isAssignableFrom(expectedType)) {
if (byRef) {
throw new IllegalArgumentException("Function " + getName()
+ " declared Structure[] at parameter "
+ index + " but array of "
+ type + " was passed");
}
for (int i=0;i < ss.length;i++) {
if (ss[i] instanceof Structure.ByReference) {
throw new IllegalArgumentException("Function " + getName()
+ " declared Structure[] at parameter "
+ index + " but element " + i
+ " is of Structure.ByReference type");
}
}
}
}
if (byRef) {
Structure.autoWrite(ss);
Pointer[] pointers = new Pointer[ss.length + 1];
+9 -31
Ver Arquivo
@@ -51,11 +51,12 @@ import java.util.WeakHashMap;
* <code>loadLibrary</code> result.
* <p>
* <b>OPTIONS</b> (an instance of {@link Map}),
* <b>TYPE_MAPPER</b> (an instance of {@link TypeMapper}) and
* <b>TYPE_MAPPER</b> (an instance of {@link TypeMapper}),
* <b>STRUCTURE_ALIGNMENT</b> (one of the alignment types defined in
* {@link Structure}) may also be defined. If no instance of the interface
* has been instantiated, these fields will be used to determine customization
* settings for structures and methods defined within the interface.
* {@link Structure}), and <b>STRING_ENCODING</b> (a {@link String}) may also
* be defined. If no instance of the interface has been instantiated, these
* fields will be used to determine customization settings for structures and
* methods defined within the interface.
* <p>
*
* @author Todd Fast, todd.fast@sun.com
@@ -117,25 +118,10 @@ public interface Library {
}
}
private static class FunctionNameMap implements FunctionMapper {
private final Map map;
public FunctionNameMap(Map map) {
this.map = new HashMap(map);
}
public String getFunctionName(NativeLibrary library, Method method) {
String name = method.getName();
if (map.containsKey(name)) {
return (String)map.get(name);
}
return name;
}
}
private final NativeLibrary nativeLibrary;
private final Class interfaceClass;
// Library invocation options
private final Map options;
private FunctionMapper functionMapper;
private final InvocationMapper invocationMapper;
private final Map functions = new WeakHashMap();
public Handler(String libname, Class interfaceClass, Map options) {
@@ -154,13 +140,11 @@ public interface Library {
options.put(OPTION_CALLING_CONVENTION,
new Integer(callingConvention));
}
if (options.get(OPTION_CLASSLOADER) == null) {
options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader());
}
this.options = options;
this.nativeLibrary = NativeLibrary.getInstance(libname, options);
functionMapper = (FunctionMapper)options.get(OPTION_FUNCTION_MAPPER);
if (functionMapper == null) {
// backward compatibility; passed-in map is itself the name map
functionMapper = new FunctionNameMap(options);
}
invocationMapper = (InvocationMapper)options.get(OPTION_INVOCATION_MAPPER);
}
@@ -212,13 +196,7 @@ public interface Library {
}
if (f.handler == null) {
// Find the function to invoke
String methodName =
functionMapper.getFunctionName(nativeLibrary, method);
if (methodName == null) {
// Just in case the function mapper screwed up
methodName = method.getName();
}
f.function = nativeLibrary.getFunction(methodName, method);
f.function = nativeLibrary.getFunction(method.getName(), method);
f.options = new HashMap(this.options);
f.options.put(Function.OPTION_INVOKING_METHOD, method);
}
+186 -74
Ver Arquivo
@@ -1,4 +1,4 @@
/* Copyright (c) 2007-2012 Timothy Wall, All Rights Reserved
/* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -92,9 +92,11 @@ import com.sun.jna.Structure.FFIType;
public final class Native implements Version {
public static final String DEFAULT_ENCODING = "utf8";
static final boolean DEBUG_LOAD = Boolean.getBoolean("jna.debug_load");
static final boolean DEBUG_JNA_LOAD = Boolean.getBoolean("jna.debug_load.jna");
// Used by tests, do not remove
private static String nativeLibraryPath = null;
static String jnidispatchPath = null;
private static Map options = new WeakHashMap();
private static Map libraries = new WeakHashMap();
private static final UncaughtExceptionHandler DEFAULT_HANDLER =
@@ -122,6 +124,7 @@ public final class Native implements Version {
private static final int TYPE_WCHAR_T = 2;
private static final int TYPE_SIZE_T = 3;
static final int MAX_ALIGNMENT;
static final int MAX_PADDING;
static {
@@ -142,8 +145,8 @@ public final class Native implements Version {
String LS = System.getProperty("line.separator");
throw new Error(LS + LS
+ "There is an incompatible JNA native library installed on this system" + LS
+ (nativeLibraryPath != null
? "(at " + nativeLibraryPath + ")" : System.getProperty("java.library.path"))
+ (jnidispatchPath != null
? "(at " + jnidispatchPath + ")" : System.getProperty("java.library.path"))
+ "." + LS
+ "To resolve this issue you may do one of the following:" + LS
+ " - remove or uninstall the offending library" + LS
@@ -151,9 +154,12 @@ public final class Native implements Version {
+ " - set jna.boot.library.path to include the path to the version of the " + LS
+ " jnidispatch library included with the JNA jar file you are using" + LS);
}
setPreserveLastError("true".equalsIgnoreCase(System.getProperty("jna.preserve_last_error", "true")));
MAX_PADDING = Platform.isSPARC() || Platform.isWindows()
MAX_ALIGNMENT = Platform.isSPARC() || Platform.isWindows()
|| (Platform.isLinux() && (Platform.isARM() || Platform.isPPC()))
|| Platform.isAIX()
|| Platform.isAndroid()
? 8 : LONG_SIZE;
MAX_PADDING = (Platform.isMac() && Platform.isPPC()) ? 8 : MAX_ALIGNMENT;
}
/** Force a dispose when this class is GC'd. */
@@ -166,7 +172,7 @@ public final class Native implements Version {
/** Properly dispose of JNA functionality. */
private static void dispose() {
NativeLibrary.disposeAll();
nativeLibraryPath = null;
jnidispatchPath = null;
}
/** Remove any automatically unpacked native library.
@@ -419,22 +425,24 @@ public final class Native implements Version {
* Expects that lock on libraries is already held
*/
private static void loadLibraryInstance(Class cls) {
if (cls != null && !libraries.containsKey(cls)) {
try {
Field[] fields = cls.getFields();
for (int i=0;i < fields.length;i++) {
Field field = fields[i];
if (field.getType() == cls
&& Modifier.isStatic(field.getModifiers())) {
// Ensure the field gets initialized by reading it
libraries.put(cls, new WeakReference(field.get(null)));
break;
synchronized(libraries) {
if (cls != null && !libraries.containsKey(cls)) {
try {
Field[] fields = cls.getFields();
for (int i=0;i < fields.length;i++) {
Field field = fields[i];
if (field.getType() == cls
&& Modifier.isStatic(field.getModifiers())) {
// Ensure the field gets initialized by reading it
libraries.put(cls, new WeakReference(field.get(null)));
break;
}
}
}
}
catch (Exception e) {
throw new IllegalArgumentException("Could not access instance of "
+ cls + " (" + e + ")");
catch (Exception e) {
throw new IllegalArgumentException("Could not access instance of "
+ cls + " (" + e + ")");
}
}
}
}
@@ -447,6 +455,8 @@ public final class Native implements Version {
if (cls == null) {
return null;
}
// Check for direct-mapped libraries, which won't necessarily
// implement com.sun.jna.Library.
synchronized(libraries) {
if (options.containsKey(cls)) {
return cls;
@@ -479,41 +489,53 @@ public final class Native implements Version {
*/
public static Map getLibraryOptions(Class type) {
synchronized(libraries) {
Class mappingClass = findEnclosingLibraryClass(type);
if (mappingClass != null) {
loadLibraryInstance(mappingClass);
if (options.containsKey(type)) {
return (Map)options.get(type);
}
else {
mappingClass = type;
}
Class mappingClass = findEnclosingLibraryClass(type);
if (mappingClass != null) {
loadLibraryInstance(mappingClass);
}
else {
mappingClass = type;
}
synchronized(libraries) {
if (options.containsKey(mappingClass)) {
Map libraryOptions = (Map)options.get(mappingClass);
options.put(type, libraryOptions);
return libraryOptions;
}
if (!options.containsKey(mappingClass)) {
Map libraryOptions = null;
try {
Field field = mappingClass.getField("OPTIONS");
field.setAccessible(true);
libraryOptions = (Map)field.get(null);
}
catch (NoSuchFieldException e) {
libraryOptions = Collections.EMPTY_MAP;
}
catch (Exception e) {
throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map ("
+ e + "): " + mappingClass);
}
// Make a clone of the original
libraryOptions = new HashMap(libraryOptions);
if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) {
libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, "TYPE_MAPPER", TypeMapper.class));
}
if (!libraryOptions.containsKey(Library.OPTION_STRUCTURE_ALIGNMENT)) {
libraryOptions.put(Library.OPTION_STRUCTURE_ALIGNMENT, lookupField(mappingClass, "STRUCTURE_ALIGNMENT", Integer.class));
}
if (!libraryOptions.containsKey(Library.OPTION_STRING_ENCODING)) {
libraryOptions.put(Library.OPTION_STRING_ENCODING, lookupField(mappingClass, "STRING_ENCODING", String.class));
}
options.put(mappingClass, libraryOptions);
Map libraryOptions = null;
try {
Field field = mappingClass.getField("OPTIONS");
field.setAccessible(true);
libraryOptions = (Map)field.get(null);
}
return (Map)options.get(mappingClass);
catch (NoSuchFieldException e) {
libraryOptions = Collections.EMPTY_MAP;
}
catch (Exception e) {
throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map ("
+ e + "): " + mappingClass);
}
// Make a clone of the original options
libraryOptions = new HashMap(libraryOptions);
if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) {
libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, "TYPE_MAPPER", TypeMapper.class));
}
if (!libraryOptions.containsKey(Library.OPTION_STRUCTURE_ALIGNMENT)) {
libraryOptions.put(Library.OPTION_STRUCTURE_ALIGNMENT, lookupField(mappingClass, "STRUCTURE_ALIGNMENT", Integer.class));
}
if (!libraryOptions.containsKey(Library.OPTION_STRING_ENCODING)) {
libraryOptions.put(Library.OPTION_STRING_ENCODING, lookupField(mappingClass, "STRING_ENCODING", String.class));
}
options.put(mappingClass, libraryOptions);
// Store the original lookup class, if different from the mapping class
if (type != mappingClass) {
options.put(type, libraryOptions);
}
return libraryOptions;
}
}
@@ -643,10 +665,20 @@ public final class Native implements Version {
String dir = dirs.nextToken();
File file = new File(new File(dir), System.mapLibraryName(libName).replace(".dylib", ".jnilib"));
String path = file.getAbsolutePath();
if (DEBUG_JNA_LOAD) {
System.out.println("Looking in " + path);
}
if (file.exists()) {
try {
if (DEBUG_JNA_LOAD) {
System.out.println("Trying " + path);
}
System.setProperty("jnidispatch.path", path);
System.load(path);
nativeLibraryPath = path;
jnidispatchPath = path;
if (DEBUG_JNA_LOAD) {
System.out.println("Found jnidispatch at " + path);
}
return;
} catch (UnsatisfiedLinkError ex) {
// Not a problem if already loaded in anoteher class loader
@@ -664,10 +696,20 @@ public final class Native implements Version {
ext = "dylib";
}
path = path.substring(0, path.lastIndexOf(orig)) + ext;
if (DEBUG_JNA_LOAD) {
System.out.println("Looking in " + path);
}
if (new File(path).exists()) {
try {
if (DEBUG_JNA_LOAD) {
System.out.println("Trying " + path);
}
System.setProperty("jnidispatch.path", path);
System.load(path);
nativeLibraryPath = path;
jnidispatchPath = path;
if (DEBUG_JNA_LOAD) {
System.out.println("Found jnidispatch at " + path);
}
return;
} catch (UnsatisfiedLinkError ex) {
System.err.println("File found at " + path + " but not loadable: " + ex.getMessage());
@@ -678,7 +720,13 @@ public final class Native implements Version {
}
if (!Boolean.getBoolean("jna.nosys")) {
try {
if (DEBUG_JNA_LOAD) {
System.out.println("Trying (via loadLibrary) " + libName);
}
System.loadLibrary(libName);
if (DEBUG_JNA_LOAD) {
System.out.println("Found jnidispatch on system path");
}
return;
}
catch(UnsatisfiedLinkError e) {
@@ -706,13 +754,21 @@ public final class Native implements Version {
throw new UnsatisfiedLinkError("Could not find JNA native support");
}
}
System.load(lib.getAbsolutePath());
nativeLibraryPath = lib.getAbsolutePath();
if (DEBUG_JNA_LOAD) {
System.out.println("Trying " + lib.getAbsolutePath());
}
System.setProperty("jnidispatch.path", lib.getAbsolutePath());
System.load(lib.getAbsolutePath());
jnidispatchPath = lib.getAbsolutePath();
if (DEBUG_JNA_LOAD) {
System.out.println("Found jnidispatch at " + jnidispatchPath);
}
// Attempt to delete immediately once jnidispatch is successfully
// loaded. This avoids the complexity of trying to do so on "exit",
// which point can vary under different circumstances (native
// compilation, dynamically loaded modules, normal application, etc).
if (isUnpacked(lib)) {
if (isUnpacked(lib)
&& !Boolean.getBoolean("jnidispatch.preserve")) {
deleteLibrary(lib);
}
}
@@ -754,6 +810,8 @@ public final class Native implements Version {
* @throws IOException if resource not found
*/
public static File extractFromResourcePath(String name, ClassLoader loader) throws IOException {
final boolean DEBUG = DEBUG_LOAD
|| (DEBUG_JNA_LOAD && name.indexOf("jnidispatch") != -1);
if (loader == null) {
loader = Thread.currentThread().getContextClassLoader();
// Context class loader is not guaranteed to be set
@@ -761,6 +819,9 @@ public final class Native implements Version {
loader = Native.class.getClassLoader();
}
}
if (DEBUG) {
System.out.println("Looking in classpath from " + loader + " for " + name);
}
String libname = name.startsWith("/") ? name : NativeLibrary.mapSharedLibraryName(name);
String resourcePath = name.startsWith("/") ? name : Platform.RESOURCE_PREFIX + "/" + libname;
if (resourcePath.startsWith("/")) {
@@ -778,6 +839,9 @@ public final class Native implements Version {
}
throw new IOException("Native library (" + resourcePath + ") not found in resource path (" + path + ")");
}
if (DEBUG) {
System.out.println("Found library resource at " + url);
}
File lib = null;
if (url.getProtocol().toLowerCase().equals("file")) {
@@ -787,6 +851,9 @@ public final class Native implements Version {
catch(URISyntaxException e) {
lib = new File(url.getPath());
}
if (DEBUG) {
System.out.println("Looking in " + lib.getAbsolutePath());
}
if (!lib.exists()) {
throw new IOException("File URL " + url + " could not be properly decoded");
}
@@ -804,7 +871,9 @@ public final class Native implements Version {
// problems with Web Start.
File dir = getTempDir();
lib = File.createTempFile(JNA_TMPLIB_PREFIX, Platform.isWindows()?".dll":null, dir);
lib.deleteOnExit();
if (!Boolean.getBoolean("jnidispatch.preserve")) {
lib.deleteOnExit();
}
fos = new FileOutputStream(lib);
int count;
byte[] buf = new byte[1024];
@@ -1084,7 +1153,7 @@ public final class Native implements Version {
* @param libName library name to which functions should be bound
*/
public static void register(String libName) {
register(getNativeClass(getCallingClass()), libName);
register(findDirectMappedClass(getCallingClass()), libName);
}
/** When called from a class static initializer, maps all native methods
@@ -1093,10 +1162,11 @@ public final class Native implements Version {
* @param lib native library to which functions should be bound
*/
public static void register(NativeLibrary lib) {
register(getNativeClass(getCallingClass()), lib);
register(findDirectMappedClass(getCallingClass()), lib);
}
static Class getNativeClass(Class cls) {
/** Find the nearest enclosing class with native methods. */
static Class findDirectMappedClass(Class cls) {
Method[] methods = cls.getDeclaredMethods();
for (int i=0;i < methods.length;i++) {
if ((methods[i].getModifiers() & Modifier.NATIVE) != 0) {
@@ -1107,7 +1177,7 @@ public final class Native implements Version {
if (idx != -1) {
String name = cls.getName().substring(0, idx);
try {
return getNativeClass(Class.forName(name, true, cls.getClassLoader()));
return findDirectMappedClass(Class.forName(name, true, cls.getClassLoader()));
}
catch(ClassNotFoundException e) {
}
@@ -1115,6 +1185,9 @@ public final class Native implements Version {
throw new IllegalArgumentException("Can't determine class with native methods from the current context (" + cls + ")");
}
/** Try to determine the class context in which a {@link #register(String)} call
was made.
*/
static Class getCallingClass() {
Class[] context = new SecurityManager() {
public Class[] getClassContext() {
@@ -1159,7 +1232,7 @@ public final class Native implements Version {
to be garbage collected.
*/
public static void unregister() {
unregister(getNativeClass(getCallingClass()));
unregister(findDirectMappedClass(getCallingClass()));
}
/** Remove all native mappings for the given class.
@@ -1433,12 +1506,7 @@ public final class Native implements Version {
}
}
String name = method.getName();
FunctionMapper fmapper = (FunctionMapper)lib.getOptions().get(Library.OPTION_FUNCTION_MAPPER);
if (fmapper != null) {
name = fmapper.getFunctionName(lib, method);
}
Function f = lib.getFunction(name, method);
Function f = lib.getFunction(method.getName(), method);
try {
handles[i] = registerMethod(cls, method.getName(),
sig, cvt,
@@ -1465,6 +1533,7 @@ public final class Native implements Version {
looking them up later.
*/
private static void cacheOptions(Class cls, Map libOptions, Object proxy) {
libOptions = new HashMap(libOptions);
synchronized(libraries) {
options.put(cls, libOptions);
if (proxy != null) {
@@ -1816,12 +1885,55 @@ public final class Native implements Version {
*/
public static native ByteBuffer getDirectByteBuffer(long addr, long length);
/** Indicate the desired attachment state for the current thread.
/** Indicate whether the JVM should detach the current native thread when
the current Java code finishes execution. Generally this is used to
avoid detaching native threads when it is known that a given thread
will be relatively long-lived and call back to Java code frequently.
<p/>
<em>Warning</em>: avoid calling {@link #detach detach(true)} on threads
spawned by the JVM; the resulting behavior is not defined.
This call is lightweight; it only results in an additional JNI
crossing if the desired state changes from its last setting.
@throws IllegalStateException if {@link #detach detach(true)} is
called on a thread created by the JVM.
*/
public static native void detach(boolean detach);
public static void detach(boolean detach) {
Thread thread = Thread.currentThread();
if (detach) {
// If a CallbackThreadInitializer was used to avoid detach,
// we won't have put that thread into the nativeThreads map.
// Performance is not as critical in that case, and since
// detach is the default behavior, force an update of the detach
// state every time. Clear the termination flag, since it's not
// needed when the native thread is detached normally.
nativeThreads.remove(thread);
Pointer p = (Pointer)nativeThreadTerminationFlag.get();
setDetachState(true, 0);
}
else {
if (!nativeThreads.containsKey(thread)) {
Pointer p = (Pointer)nativeThreadTerminationFlag.get();
nativeThreads.put(thread, p);
setDetachState(false, p.peer);
}
}
}
static Pointer getTerminationFlag(Thread t) {
return (Pointer)nativeThreads.get(t);
}
private static Map nativeThreads = Collections.synchronizedMap(new WeakHashMap());
private static ThreadLocal nativeThreadTerminationFlag =
new ThreadLocal() {
protected Object initialValue() {
Memory m = new Memory(4);
m.clear();
return m;
}
};
private static native void setDetachState(boolean detach, long terminationFlag);
private static class Buffers {
static boolean isBuffer(Class cls) {
+84 -22
Ver Arquivo
@@ -58,6 +58,8 @@ import java.util.StringTokenizer;
* resource will be extracted to <code>jna.tmpdir</code> for loading, and
* later removed (but only if <code>jna.nounpack</code> is false or not set).
* </ol>
* You may set the system property <code>jna.debug_load=true</code> to make
* JNA print the steps of its library search to the console.
* @author Wayne Meissner, split library loading from Function.java
* @author twall
*/
@@ -68,6 +70,7 @@ public class NativeLibrary {
private final String libraryPath;
private final Map functions = new HashMap();
final int callFlags;
private String encoding;
final Map options;
private static final Map libraries = new HashMap();
@@ -89,13 +92,13 @@ public class NativeLibrary {
this.libraryPath = libraryPath;
this.handle = handle;
Object option = options.get(Library.OPTION_CALLING_CONVENTION);
int callingConvention = option instanceof Integer
? ((Integer)option).intValue() : Function.C_CONVENTION;
int callingConvention = option instanceof Number
? ((Number)option).intValue() : Function.C_CONVENTION;
this.callFlags = callingConvention;
this.options = options;
String encoding = (String)options.get(Library.OPTION_STRING_ENCODING);
if (encoding == null) {
encoding = Native.getDefaultStringEncoding();
this.encoding = (String)options.get(Library.OPTION_STRING_ENCODING);
if (this.encoding == null) {
this.encoding = Native.getDefaultStringEncoding();
}
// Special workaround for w32 kernel32.GetLastError
@@ -103,10 +106,10 @@ public class NativeLibrary {
if (Platform.isWindows() && "kernel32".equals(this.libraryName.toLowerCase())) {
synchronized(functions) {
Function f = new Function(this, "GetLastError", Function.ALT_CONVENTION, encoding) {
Object invoke(Object[] args, Class returnType, boolean b) {
return new Integer(Native.getLastError());
}
};
Object invoke(Object[] args, Class returnType, boolean b) {
return new Integer(Native.getLastError());
}
};
functions.put(functionKey("GetLastError", callFlags, encoding), f);
}
}
@@ -122,6 +125,10 @@ public class NativeLibrary {
}
private static NativeLibrary loadLibrary(String libraryName, Map options) {
if (Native.DEBUG_LOAD) {
System.out.println("Looking for library '" + libraryName + "'");
}
boolean isAbsolutePath = new File(libraryName).isAbsolute();
List searchPath = new LinkedList();
int openFlags = openFlags(options);
@@ -130,6 +137,9 @@ public class NativeLibrary {
// attempt any library name variations
String webstartPath = Native.getWebStartLibraryPath(libraryName);
if (webstartPath != null) {
if (Native.DEBUG_LOAD) {
System.out.println("Adding web start path " + webstartPath);
}
searchPath.add(webstartPath);
}
@@ -143,6 +153,9 @@ public class NativeLibrary {
}
}
if (Native.DEBUG_LOAD) {
System.out.println("Adding paths from jna.library.path: " + System.getProperty("jna.library.path"));
}
searchPath.addAll(initPaths("jna.library.path"));
String libraryPath = findLibraryPath(libraryName, searchPath);
long handle = 0;
@@ -152,15 +165,24 @@ public class NativeLibrary {
// name if it cannot find the library.
//
try {
if (Native.DEBUG_LOAD) {
System.out.println("Trying " + libraryPath);
}
handle = Native.open(libraryPath, openFlags);
}
catch(UnsatisfiedLinkError e) {
// Add the system paths back for all fallback searching
if (Native.DEBUG_LOAD) {
System.out.println("Adding system paths: " + librarySearchPath);
}
searchPath.addAll(librarySearchPath);
}
try {
if (handle == 0) {
libraryPath = findLibraryPath(libraryName, searchPath);
if (Native.DEBUG_LOAD) {
System.out.println("Trying " + libraryPath);
}
handle = Native.open(libraryPath, openFlags);
if (handle == 0) {
throw new UnsatisfiedLinkError("Failed to load library '" + libraryName + "'");
@@ -173,6 +195,9 @@ public class NativeLibrary {
// path, not found in any properties
if (Platform.isAndroid()) {
try {
if (Native.DEBUG_LOAD) {
System.out.println("Preload (via System.loadLibrary) " + libraryName);
}
System.loadLibrary(libraryName);
handle = Native.open(libraryPath, openFlags);
}
@@ -182,9 +207,15 @@ public class NativeLibrary {
//
// Failed to load the library normally - try to match libfoo.so.*
//
if (Native.DEBUG_LOAD) {
System.out.println("Looking for version variants");
}
libraryPath = matchLibrary(libraryName, searchPath);
if (libraryPath != null) {
try {
if (Native.DEBUG_LOAD) {
System.out.println("Trying " + libraryPath);
}
try {
handle = Native.open(libraryPath, openFlags);
}
catch(UnsatisfiedLinkError e2) { e = e2; }
@@ -193,9 +224,15 @@ public class NativeLibrary {
// Search framework libraries on OS X
else if (Platform.isMac()
&& !libraryName.endsWith(".dylib")) {
if (Native.DEBUG_LOAD) {
System.out.println("Looking for matching frameworks");
}
libraryPath = matchFramework(libraryName);
if (libraryPath != null) {
try {
if (Native.DEBUG_LOAD) {
System.out.println("Trying " + libraryPath);
}
handle = Native.open(libraryPath, openFlags);
}
catch(UnsatisfiedLinkError e2) { e = e2; }
@@ -203,9 +240,17 @@ public class NativeLibrary {
}
// Try the same library with a "lib" prefix
else if (Platform.isWindows() && !isAbsolutePath) {
if (Native.DEBUG_LOAD) {
System.out.println("Looking for lib- prefix");
}
libraryPath = findLibraryPath("lib" + libraryName, searchPath);
try { handle = Native.open(libraryPath, openFlags); }
catch(UnsatisfiedLinkError e2) { e = e2; }
if (libraryPath != null) {
if (Native.DEBUG_LOAD) {
System.out.println("Trying " + libraryPath);
}
try { handle = Native.open(libraryPath, openFlags); }
catch(UnsatisfiedLinkError e2) { e = e2; }
}
}
// As a last resort, try to extract the library from the class
// path, using the current context class loader.
@@ -213,6 +258,7 @@ public class NativeLibrary {
try {
File embedded = Native.extractFromResourcePath(libraryName, (ClassLoader)options.get(Library.OPTION_CLASSLOADER));
handle = Native.open(embedded.getAbsolutePath());
libraryPath = embedded.getAbsolutePath();
// Don't leave temporary files around
if (Native.isUnpacked(embedded)) {
Native.deleteLibrary(embedded);
@@ -226,6 +272,9 @@ public class NativeLibrary {
+ e.getMessage());
}
}
if (Native.DEBUG_LOAD) {
System.out.println("Found library '" + libraryName + "' at " + libraryPath);
}
return new NativeLibrary(libraryName, libraryPath, handle, options);
}
@@ -382,7 +431,8 @@ public class NativeLibrary {
/**
* Add a path to search for the specified library, ahead of any system
* paths.
* paths. This is similar to setting <code>jna.library.path</code>, but
* only extends the search path for a single library.
*
* @param libraryName The name of the library to use the path for
* @param path The path to use when trying to load the library
@@ -421,12 +471,24 @@ public class NativeLibrary {
* function from the library.
*
* @param name
* Name of the native function to be linked with
* Name of the native function to be linked with. Uses a
* function mapper option if one was provided to
* transform the name.
* @param method
* Method to which the native function is to be mapped
* @throws UnsatisfiedLinkError if the function is not found
*/
Function getFunction(String name, Method method) {
FunctionMapper mapper = (FunctionMapper)
options.get(Library.OPTION_FUNCTION_MAPPER);
if (mapper != null) {
name = mapper.getFunctionName(this, method);
}
// If there's native method profiler prefix, strip it
String prefix = System.getProperty("jna.profiler.prefix", "$$YJP$$");
if (name.startsWith(prefix)) {
name = name.substring(prefix.length());
}
int flags = this.callFlags;
Class[] etypes = method.getExceptionTypes();
for (int i=0;i < etypes.length;i++) {
@@ -448,7 +510,7 @@ public class NativeLibrary {
* @throws UnsatisfiedLinkError if the function is not found
*/
public Function getFunction(String functionName, int callFlags) {
return getFunction(functionName, callFlags, Native.getDefaultStringEncoding());
return getFunction(functionName, callFlags, encoding);
}
/**
@@ -687,13 +749,13 @@ public class NativeLibrary {
searchPath = Arrays.asList(new String[] { lib.getParent() });
}
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
return (filename.startsWith("lib" + libName + ".so")
|| (filename.startsWith(libName + ".so")
&& libName.startsWith("lib")))
&& isVersionedName(filename);
}
};
public boolean accept(File dir, String filename) {
return (filename.startsWith("lib" + libName + ".so")
|| (filename.startsWith(libName + ".so")
&& libName.startsWith("lib")))
&& isVersionedName(filename);
}
};
List matches = new LinkedList();
for (Iterator it = searchPath.iterator(); it.hasNext(); ) {
+7 -1
Ver Arquivo
@@ -262,10 +262,16 @@ public final class Platform {
osPrefix = "sunos-" + arch;
break;
case Platform.FREEBSD:
osPrefix = "freebsd-" + arch;
break;
case Platform.OPENBSD:
osPrefix = "openbsd-" + arch;
break;
case Platform.NETBSD:
osPrefix = "netbsd-" + arch;
break;
case Platform.KFREEBSD:
osPrefix = "bsd-" + arch;
osPrefix = "kfreebsd-" + arch;
break;
default:
osPrefix = name.toLowerCase();
+21 -3
Ver Arquivo
@@ -1207,7 +1207,7 @@ v * @param wide whether to convert from a wide or standard C string
* <code>char</code> using the encoding indicated by {@link
* Native#getDefaultStringEncoding()}.
*
* @deprecated use {@link setWideString(long,String)} instead.
* @deprecated use {@link #setWideString(long,String)} instead.
*/
public void setString(long offset, String value, boolean wide) {
if (wide) {
@@ -1239,7 +1239,7 @@ v * @param wide whether to convert from a wide or standard C string
* @param value <code>WString</code> value to set
*/
public void setString(long offset, WString value) {
setWideString(offset, value.toString());
setWideString(offset, value == null ? null : value.toString());
}
/**
@@ -1308,6 +1308,12 @@ v * @param wide whether to convert from a wide or standard C string
private static class Opaque extends Pointer {
private Opaque(long peer) { super(peer); }
private final String MSG = "This pointer is opaque: " + this;
public Pointer share(long offset, long size) {
throw new UnsupportedOperationException(MSG);
}
public void clear(long size) {
throw new UnsupportedOperationException(MSG);
}
public long indexOf(long offset, byte value) {
throw new UnsupportedOperationException(MSG);
}
@@ -1332,6 +1338,9 @@ v * @param wide whether to convert from a wide or standard C string
public void read(long bOff, double[] buf, int index, int length) {
throw new UnsupportedOperationException(MSG);
}
public void read(long bOff, Pointer[] buf, int index, int length) {
throw new UnsupportedOperationException(MSG);
}
public void write(long bOff, byte[] buf, int index, int length) {
throw new UnsupportedOperationException(MSG);
}
@@ -1353,6 +1362,12 @@ v * @param wide whether to convert from a wide or standard C string
public void write(long bOff, double[] buf, int index, int length) {
throw new UnsupportedOperationException(MSG);
}
public void write(long bOff, Pointer[] buf, int index, int length) {
throw new UnsupportedOperationException(MSG);
}
public ByteBuffer getByteBuffer(long offset, long length) {
throw new UnsupportedOperationException(MSG);
}
public byte getByte(long bOff) {
throw new UnsupportedOperationException(MSG);
}
@@ -1413,8 +1428,11 @@ v * @param wide whether to convert from a wide or standard C string
public void setWideString(long offset, String value) {
throw new UnsupportedOperationException(MSG);
}
public void setMemory(long offset, long size, byte value) {
throw new UnsupportedOperationException(MSG);
}
public String toString() {
return "opaque@0x" + Long.toHexString(peer);
return "const@0x" + Long.toHexString(peer);
}
}
}
+28 -30
Ver Arquivo
@@ -106,10 +106,6 @@ public abstract class Structure {
*/
public interface ByReference { }
static final boolean isPPC = Platform.isPPC();
static final boolean isSPARC = Platform.isSPARC();
static final boolean isARM = Platform.isARM();
/** Use the platform default alignment. */
public static final int ALIGN_DEFAULT = 0;
/** No alignment, place all fields on nearest 1-byte boundary */
@@ -126,12 +122,6 @@ public abstract class Structure {
/** Align to an 8-byte boundary. */
//public static final int ALIGN_8 = 6;
static final int MAX_GNUC_ALIGNMENT =
isSPARC
|| ((isPPC || isARM)
&& (Platform.isLinux() || Platform.isAndroid()))
|| Platform.isAIX()
? 8 : Native.LONG_SIZE;
protected static final int CALCULATE_SIZE = -1;
static final Map layoutInfo = new WeakHashMap();
static final Map fieldOrder = new WeakHashMap();
@@ -217,10 +207,7 @@ public abstract class Structure {
*/
private void initializeTypeMapper(TypeMapper mapper) {
if (mapper == null) {
Class declaring = getClass().getDeclaringClass();
if (declaring != null) {
mapper = Native.getTypeMapper(declaring);
}
mapper = Native.getTypeMapper(getClass());
}
this.typeMapper = mapper;
layoutChanged();
@@ -261,9 +248,7 @@ public abstract class Structure {
protected void setAlignType(int alignType) {
this.alignType = alignType;
if (alignType == ALIGN_DEFAULT) {
Class declaring = getClass().getDeclaringClass();
if (declaring != null)
alignType = Native.getStructureAlignment(declaring);
alignType = Native.getStructureAlignment(getClass());
if (alignType == ALIGN_DEFAULT) {
if (Platform.isWindows())
alignType = ALIGN_MSVC;
@@ -621,12 +606,16 @@ public abstract class Structure {
Structure s1 = (Structure)reading().get(address);
if (s1 != null && type.equals(s1.getClass())) {
s = s1;
s.autoRead();
}
else {
s = newInstance(type, address);
s.conditionalAutoRead();
}
}
s.autoRead();
else {
s.autoRead();
}
}
return s;
}
@@ -635,7 +624,7 @@ public abstract class Structure {
* updated from the contents of native memory.
*/
// TODO: make overridable method with calculated native type, offset, etc
Object readField(StructField structField) {
protected Object readField(StructField structField) {
// Get the offset of the field
int offset = structField.offset;
@@ -745,7 +734,7 @@ public abstract class Structure {
writeField(structField);
}
void writeField(StructField structField) {
protected void writeField(StructField structField) {
if (structField.isReadOnly)
return;
@@ -1154,6 +1143,9 @@ public abstract class Structure {
}
// Align fields as appropriate
if (fieldAlignment == 0) {
throw new Error("Field alignment is zero for field '" + structField.name + "' within " + getClass());
}
info.alignment = Math.max(info.alignment, fieldAlignment);
if ((calculatedSize % fieldAlignment) != 0) {
calculatedSize += fieldAlignment - (calculatedSize % fieldAlignment);
@@ -1312,10 +1304,10 @@ public abstract class Structure {
else if (actualAlignType == ALIGN_GNUC) {
// NOTE this is published ABI for 32-bit gcc/linux/x86, osx/x86,
// and osx/ppc. osx/ppc special-cases the first element
if (!isFirstElement || !(Platform.isMac() && isPPC)) {
alignment = Math.min(MAX_GNUC_ALIGNMENT, alignment);
if (!isFirstElement || !(Platform.isMac() && Platform.isPPC())) {
alignment = Math.min(Native.MAX_ALIGNMENT, alignment);
}
if (!isFirstElement && Platform.isAIX() && (type.getName().equals("double"))) {
if (!isFirstElement && Platform.isAIX() && (type == double.class || type == Double.class)) {
alignment = 4;
}
}
@@ -1577,15 +1569,21 @@ public abstract class Structure {
}
/** Called from native code only; same as {@link
* #newInstance(Class,Pointer)}, except that it additionally performs
* #newInstance(Class,Pointer)}, except that it additionally calls
* {@link #conditionalAutoRead()}.
*/
private static Structure newInstance(Class type, long init) throws IllegalArgumentException {
Structure s = newInstance(type, init == 0 ? PLACEHOLDER_MEMORY : new Pointer(init));
if (init != 0) {
s.conditionalAutoRead();
private static Structure newInstance(Class type, long init) {
try {
Structure s = newInstance(type, init == 0 ? PLACEHOLDER_MEMORY : new Pointer(init));
if (init != 0) {
s.conditionalAutoRead();
}
return s;
}
catch(Throwable e) {
System.err.println("JNA: Error creating structure: " + e);
return null;
}
return s;
}
/** Create a new Structure instance of the given type, initialized with
@@ -1665,7 +1663,7 @@ public abstract class Structure {
return null;
}
static class StructField extends Object {
protected static class StructField extends Object {
public String name;
public Class type;
public Field field;
+5 -4
Ver Arquivo
@@ -191,7 +191,7 @@ public abstract class Union extends Structure {
}
/** Only the currently selected field will be written. */
void writeField(StructField field) {
protected void writeField(StructField field) {
if (field == activeField) {
super.writeField(field);
}
@@ -201,7 +201,7 @@ public abstract class Union extends Structure {
* selected. Structures may contain pointer-based fields which can
* crash the VM if not properly initialized.
*/
Object readField(StructField field) {
protected Object readField(StructField field) {
if (field == activeField
|| (!Structure.class.isAssignableFrom(field.type)
&& !String.class.isAssignableFrom(field.type)
@@ -209,8 +209,9 @@ public abstract class Union extends Structure {
return super.readField(field);
}
// Field not accessible
// TODO: read structure, to the extent possible; need a "recursive"
// flag to "read" to indicate we want to avoid pointer-based fields
// TODO: read by-value structures, to the extent possible; need a
// "read cautiously" method to "read" to indicate we want to avoid
// pointer-based fields
return null;
}
+24 -1
Ver Arquivo
@@ -406,6 +406,29 @@ public class ArgumentsMarshalTest extends TestCase {
}
}
public void testRejectIncompatibleStructureArrayArgument() {
TestLibrary.CheckFieldAlignment s1 = new TestLibrary.CheckFieldAlignment.ByReference();
TestLibrary.CheckFieldAlignment[] autoArray = (TestLibrary.CheckFieldAlignment[])s1.toArray(3);
try {
lib.modifyStructureArray(autoArray, autoArray.length);
}
catch(IllegalArgumentException e) {
}
TestLibrary.CheckFieldAlignment.ByReference[] byRefArray =
(TestLibrary.CheckFieldAlignment.ByReference[])s1.toArray(3);
try {
lib.modifyStructureArray(byRefArray, byRefArray.length);
}
catch(IllegalArgumentException e) {
}
TestLibrary.CheckFieldAlignment[] arrayWithRefElements = { autoArray[0], autoArray[1], autoArray[2] };
try {
lib.modifyStructureArray(arrayWithRefElements, arrayWithRefElements.length);
}
catch(IllegalArgumentException e) {
}
}
/** When passing an array of <code>struct*</code> to native, be sure to
invoke <code>Structure.write()</code> on each of the elements. */
public void testWriteStructureByReferenceArrayArgumentMemory() {
@@ -482,7 +505,7 @@ public class ArgumentsMarshalTest extends TestCase {
}
}
public void testInvalidArgument() {
public void testUnsupportedJavaObjectArgument() {
try {
lib.returnBooleanArgument(this);
fail("Unsupported Java objects should be rejected");
+125 -38
Ver Arquivo
@@ -1,4 +1,4 @@
/* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved
/* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -13,6 +13,7 @@
package com.sun.jna;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.lang.ref.WeakReference;
import java.util.Arrays;
@@ -28,19 +29,23 @@ import junit.framework.TestCase;
import com.sun.jna.Callback.UncaughtExceptionHandler;
import com.sun.jna.CallbacksTest.TestLibrary.CbCallback;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.W32APIOptions;
/** Exercise callback-related functionality.
*
* @author twall@users.sf.net
*/
//@SuppressWarnings("unused")
public class CallbacksTest extends TestCase {
public class CallbacksTest extends TestCase implements Paths {
private static final String UNICODE = "[\u0444]";
private static final double DOUBLE_MAGIC = -118.625d;
private static final float FLOAT_MAGIC = -118.625f;
private static final int THREAD_TIMEOUT = 5000;
public static class SmallTestStructure extends Structure {
public double value;
public static int allocations = 0;
@@ -86,7 +91,7 @@ public class CallbacksTest extends TestCase {
void callback();
}
void callVoidCallback(VoidCallback c);
void callVoidCallbackThreaded(VoidCallback c, int count, int ms);
void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name);
interface VoidCallbackCustom extends Callback {
void customMethodName();
}
@@ -184,6 +189,7 @@ public class CallbacksTest extends TestCase {
}
TestLibrary lib;
protected void setUp() {
lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class);
}
@@ -232,9 +238,20 @@ public class CallbacksTest extends TestCase {
}
}
public void testThrowOnMultiplyMappedCallback() {
try {
Pointer p = new Pointer(getName().hashCode());
CallbackReference.getCallback(TestLibrary.VoidCallback.class, p);
CallbackReference.getCallback(TestLibrary.ByteCallback.class, p);
fail("Multiply-mapped callback should fail");
}
catch(IllegalStateException e) {
}
}
public void testNoMethodCallback() {
try {
CallbackReference.getCallback(TestLibrary.NoMethodCallback.class, new Pointer(1));
CallbackReference.getCallback(TestLibrary.NoMethodCallback.class, new Pointer(getName().hashCode()));
fail("Callback with no callback method should fail");
}
catch(IllegalArgumentException e) {
@@ -242,12 +259,12 @@ public class CallbacksTest extends TestCase {
}
public void testCustomMethodCallback() {
CallbackReference.getCallback(TestLibrary.CustomMethodCallback.class, new Pointer(1));
CallbackReference.getCallback(TestLibrary.CustomMethodCallback.class, new Pointer(getName().hashCode()));
}
public void testTooManyMethodsCallback() {
try {
CallbackReference.getCallback(TestLibrary.TooManyMethodsCallback.class, new Pointer(1));
CallbackReference.getCallback(TestLibrary.TooManyMethodsCallback.class, new Pointer(getName().hashCode()));
fail("Callback lookup with too many methods should fail");
}
catch(IllegalArgumentException e) {
@@ -255,19 +272,19 @@ public class CallbacksTest extends TestCase {
}
public void testMultipleMethodsCallback() {
CallbackReference.getCallback(TestLibrary.MultipleMethodsCallback.class, new Pointer(1));
CallbackReference.getCallback(TestLibrary.MultipleMethodsCallback.class, new Pointer(getName().hashCode()));
}
public void testNativeFunctionPointerStringValue() {
Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(1));
Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode()));
Class cls = CallbackReference.findCallbackClass(cb.getClass());
assertTrue("toString should include Java Callback type: " + cb + " ("
+ cls + ")", cb.toString().indexOf(cls.getName()) != -1);
}
public void testLookupSameCallback() {
Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(1));
Callback cb2 = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(1));
Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode()));
Callback cb2 = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode()));
assertEquals("Callback lookups for same pointer should return same Callback object", cb, cb2);
}
@@ -883,6 +900,24 @@ public class CallbacksTest extends TestCase {
assertTrue("Callback with custom method name not called", called[0]);
}
public void testDisallowDetachFromJVMThread() {
final boolean[] called = {false};
final boolean[] exceptionThrown = {true};
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
public void callback() {
called[0] = true;
try {
Native.detach(true);
}
catch(IllegalStateException e) {
}
}
};
lib.callVoidCallback(cb);
assertTrue("Callback not called", called[0]);
assertTrue("Native.detach(true) should throw IllegalStateException when called from JVM thread", exceptionThrown[0]);
}
public void testCustomCallbackVariedInheritance() {
final boolean[] called = {false};
TestLibrary.VoidCallbackCustom cb =
@@ -995,15 +1030,22 @@ public class CallbacksTest extends TestCase {
CallbackThreadInitializer cti,
int repeat, int sleepms,
int[] called) throws Exception {
callThreadedCallback(cb, cti, repeat, sleepms, called, repeat);
}
protected void callThreadedCallback(TestLibrary.VoidCallback cb,
CallbackThreadInitializer cti,
int repeat, int sleepms,
int[] called, int returnAfter) throws Exception {
if (cti != null) {
Native.setCallbackThreadInitializer(cb, cti);
}
lib.callVoidCallbackThreaded(cb, repeat, sleepms);
lib.callVoidCallbackThreaded(cb, repeat, sleepms, getName());
long start = System.currentTimeMillis();
while (called[0] < repeat) {
while (called[0] < returnAfter) {
Thread.sleep(10);
if (System.currentTimeMillis() - start > 5000) {
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
fail("Timed out waiting for callback, invoked " + called[0] + " times so far");
}
}
@@ -1063,7 +1105,7 @@ public class CallbacksTest extends TestCase {
}
}
};
callThreadedCallback(cb, init, 1, 5000, called);
callThreadedCallback(cb, init, 2, 2000, called, 1);
assertTrue("Callback thread not attached as daemon", daemon[0]);
assertEquals("Callback thread name not applied", tname, name[0]);
@@ -1073,6 +1115,22 @@ public class CallbacksTest extends TestCase {
throw new Error("VM incorrectly reports Thread.isAlive() == false within callback");
}
assertTrue("Thread should still be alive", t[0].isAlive());
long start = System.currentTimeMillis();
while (called[0] < 2) {
Thread.sleep(10);
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
fail("Timed out waiting for second callback invocation, which indicates detach");
}
}
start = System.currentTimeMillis();
while (t[0].isAlive()) {
Thread.sleep(10);
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
fail("Timed out waiting for thread to detach and terminate");
}
}
}
// Detach preference is indicated by the initializer. Thread is attached
@@ -1084,7 +1142,7 @@ public class CallbacksTest extends TestCase {
final int COUNT = 5;
CallbackThreadInitializer init = new CallbackThreadInitializer(true, false) {
public String getName(Callback cb) {
return CallbacksTest.this.getName() + " thread " + called[0];
return "Test thread (native) for " + CallbacksTest.this.getName() + " (call count: " + called[0] + ")";
}
};
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
@@ -1100,31 +1158,47 @@ public class CallbacksTest extends TestCase {
}
// Thread object is never GC'd on linux-amd64 and darwin-amd64 (w/openjdk7)
public void testAttachedThreadCleanupOnExit() throws Exception {
public void testCleanupUndetachedThreadOnThreadExit() throws Exception {
final Set threads = new HashSet();
final int[] called = { 0 };
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
public void callback() {
threads.add(new WeakReference(Thread.currentThread()));
if (++called[0] == 1) {
Thread.currentThread().setName("Thread to be cleaned up");
Thread.currentThread().setName(getName() + " (Thread to be cleaned up)");
}
Native.detach(false);
Native.detach(false);
}
};
CallbackThreadInitializer asDaemon = new CallbackThreadInitializer(true);
callThreadedCallback(cb, asDaemon, 1, 0, called);
while (threads.size() == 0) {
// Always attach as daemon to ensure tests will exit
CallbackThreadInitializer asDaemon = new CallbackThreadInitializer(true) {
public String getName(Callback cb) {
return "Test thread (native) for " + CallbacksTest.this.getName();
}
};
callThreadedCallback(cb, asDaemon, 2, 100, called);
// Wait for it to start up
while (threads.size() == 0 && called[0] == 0) {
Thread.sleep(10);
}
long start = System.currentTimeMillis();
WeakReference ref = (WeakReference)threads.iterator().next();
while (ref.get() != null) {
System.gc();
Thread.sleep(10);
if (System.currentTimeMillis() - start > 10000) {
Thread.sleep(100);
Thread[] remaining = new Thread[Thread.activeCount()];
Thread.enumerate(remaining);
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
Thread t = (Thread)ref.get();
fail("Timed out waiting for attached thread to be detached on exit and disposed: " + t + " alive: " + t.isAlive() + " daemon " + t.isDaemon());
Pointer terminationFlag = Native.getTerminationFlag(t);
assertNotNull("Native thread termination flag is missing", terminationFlag);
if (terminationFlag.getInt(0) == 0) {
fail("Timed out waiting for native attached thread to be GC'd: " + t + " alive: "
+ t.isAlive() + " daemon: " + t.isDaemon() + "\n" + Arrays.asList(remaining));
}
System.err.println("Warning: JVM did not GC Thread mapping after native thread terminated");
break;
}
}
}
@@ -1142,6 +1216,7 @@ public class CallbacksTest extends TestCase {
// detach on final invocation
int count = called[0] + 1;
if (count == 1) {
Thread.currentThread().setName("Native thread for " + getName());
Native.detach(false);
}
else if (count == COUNT) {
@@ -1152,25 +1227,16 @@ public class CallbacksTest extends TestCase {
};
callThreadedCallback(cb, null, COUNT, 100, called);
assertEquals("Multiple callbacks in the same native thread should use the same Thread mapping: " + threads,
1, threads.size());
assertEquals("Multiple callbacks in the same native thread should use the same Thread mapping: "
+ threads, 1, threads.size());
Thread thread = (Thread)threads.iterator().next();
long start = System.currentTimeMillis();
while (thread.isAlive()) {
System.gc();
Thread.sleep(10);
if (System.currentTimeMillis() - start > 5000) {
PrintStream ps = System.err;
ByteArrayOutputStream s = new ByteArrayOutputStream();
System.setErr(new PrintStream(s));
try {
thread.dumpStack();
}
finally {
System.setErr(ps);
}
fail("Timed out waiting for callback thread " + thread + " to die: " + s);
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
fail("Timed out waiting for native thread " + thread + " to finish");
}
}
}
@@ -1191,6 +1257,26 @@ public class CallbacksTest extends TestCase {
lib.callVoidCallback(cb);
assertTrue("Callback not called", called[0]);
// Check module information
Pointer fp = CallbackReference.getFunctionPointer(cb);
NativeLibrary kernel32 = NativeLibrary.getInstance("kernel32", W32APIOptions.DEFAULT_OPTIONS);
Function f = kernel32.getFunction("GetModuleHandleExW");
final int GET_MODULE_HANDLE_FROM_ADDRESS = 0x4;
PointerByReference pref = new PointerByReference();
int result = f.invokeInt(new Object[] { new Integer(GET_MODULE_HANDLE_FROM_ADDRESS), fp, pref });
assertTrue("GetModuleHandleEx(fptr) failed: " + Native.getLastError(), result != 0);
f = kernel32.getFunction("GetModuleFileNameW");
char[] buf = new char[1024];
result = f.invokeInt(new Object[] { pref.getValue(), buf, buf.length });
assertTrue("GetModuleFileName(fptr) failed: " + Native.getLastError(), result != 0);
f = kernel32.getFunction("GetModuleHandleW");
Pointer handle = f.invokePointer(new Object[] { Native.jnidispatchPath != null ? Native.jnidispatchPath : "jnidispatch" });
assertNotNull("GetModuleHandle(\"jnidispatch\") failed: " + Native.getLastError(), handle);
assertEquals("Wrong module HANDLE for DLL function pointer", handle, pref.getValue());
// Check slot re-use
Map refs = new WeakHashMap(callbackCache());
assertTrue("Callback not cached", refs.containsKey(cb));
CallbackReference ref = (CallbackReference)refs.get(cb);
@@ -1226,7 +1312,8 @@ public class CallbacksTest extends TestCase {
cbstruct = ref.cbstruct;
assertTrue("Callback not called", called[0]);
assertEquals("Same (in-DLL) address should be re-used for DLL callbacks", first_fptr, cbstruct.getPointer(0));
assertEquals("Same (in-DLL) address should be re-used for DLL callbacks after callback is GCd",
first_fptr, cbstruct.getPointer(0));
}
public void testThrowOutOfMemoryWhenDLLCallbacksExhausted() throws Exception {
@@ -124,6 +124,7 @@ public class DirectArgumentsMarshalTest extends ArgumentsMarshalTest {
public void testWriteStructureArrayArgumentMemory() { }
public void testUninitializedStructureArrayArgument() { }
public void testRejectNoncontiguousStructureArrayArgument() { }
public void testRejectIncompatibleStructureArrayArgument() { }
public void testWideStringArrayArgument() { }
public void testPointerArrayArgument() { }
public void testNativeMappedArrayArgument() { }
+1 -1
Ver Arquivo
@@ -42,7 +42,7 @@ public class DirectCallbacksTest extends CallbacksTest {
public native Int32CallbackX returnCallback();
public native Int32CallbackX returnCallbackArgument(Int32CallbackX cb);
public native void callVoidCallback(VoidCallback c);
public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms);
public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name);
public native int callInt32Callback(CustomCallback cb, int arg1, int arg2);
public native void callCallbackInStruct(CbStruct s);
+130 -8
Ver Arquivo
@@ -16,10 +16,15 @@ import junit.framework.*;
import com.sun.jna.*;
import com.sun.jna.ptr.PointerByReference;
import java.lang.ref.*;
import java.lang.reflect.Method;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//@SuppressWarnings("unused")
public class DirectTest extends TestCase implements Paths {
@@ -125,7 +130,6 @@ public class DirectTest extends TestCase implements Paths {
}
}
// Fails under clover
public void testRegisterMethods() throws Exception {
// Use a dedicated class loader to ensure the class can be gc'd
String name = "com.sun.jna.DirectTest$MathLibrary";
@@ -159,20 +163,138 @@ public class DirectTest extends TestCase implements Paths {
public void testFindNativeClass() {
class UnregisterLibrary {
class Inner {
public Class getNativeClass() {
return getNativeClassInner();
public Class findDirectMappedClass() {
return findDirectMappedClassInner();
}
public Class getNativeClassInner() {
return Native.getNativeClass(Native.getCallingClass());
public Class findDirectMappedClassInner() {
return Native.findDirectMappedClass(Native.getCallingClass());
};
}
public native double cos(double x);
public Class getNativeClass() {
return new Inner().getNativeClass();
public Class findDirectMappedClass() {
return new Inner().findDirectMappedClass();
};
}
assertEquals("Wrong native class found",
UnregisterLibrary.class, new UnregisterLibrary().getNativeClass());
UnregisterLibrary.class, new UnregisterLibrary().findDirectMappedClass());
}
public static class DirectMapping {
public static class DirectStructure extends Structure {
public int field;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "field" });
}
}
public static interface DirectCallback extends Callback {
void invoke();
}
public DirectMapping(Map options) {
Native.register(getClass(), NativeLibrary.getInstance("testlib", options));
}
}
public void testGetOptionsForDirectMappingWithMemberInitializer() {
Class[] classes = {
DirectMapping.class,
DirectMapping.DirectStructure.class,
DirectMapping.DirectCallback.class,
};
final TypeMapper mapper = new DefaultTypeMapper();
final int alignment = Structure.ALIGN_NONE;
final String encoding = System.getProperty("file.encoding");
Map options = new HashMap();
options.put(Library.OPTION_TYPE_MAPPER, mapper);
options.put(Library.OPTION_STRUCTURE_ALIGNMENT, alignment);
options.put(Library.OPTION_STRING_ENCODING, encoding);
DirectMapping lib = new DirectMapping(options);
for (int i=0;i < classes.length;i++) {
assertEquals("Wrong type mapper for direct mapping " + classes[i],
mapper, Native.getTypeMapper(classes[i]));
assertEquals("Wrong alignment for direct mapping " + classes[i],
alignment, Native.getStructureAlignment(classes[i]));
assertEquals("Wrong encoding for direct mapping " + classes[i],
encoding, Native.getStringEncoding(classes[i]));
Object last = Native.getLibraryOptions(classes[i]);;
assertSame("Options not cached", last, Native.getLibraryOptions(classes[i]));
}
}
public static class DirectMappingStatic {
final static TypeMapper TEST_MAPPER = new DefaultTypeMapper();
final static int TEST_ALIGNMENT = Structure.ALIGN_DEFAULT;
final static String TEST_ENCODING = System.getProperty("file.encoding");
final static Map TEST_OPTIONS = new HashMap() {
{
put(Library.OPTION_TYPE_MAPPER, TEST_MAPPER);
put(Library.OPTION_STRUCTURE_ALIGNMENT, TEST_ALIGNMENT);
put(Library.OPTION_STRING_ENCODING, TEST_ENCODING);
}
};
static {
Native.register(DirectMappingStatic.class, NativeLibrary.getInstance("testlib", TEST_OPTIONS));
}
public static class DirectStructure extends Structure {
public int field;
protected List getFieldOrder() {
return Arrays.asList(new String[] { "field" });
}
}
public static interface DirectCallback extends Callback {
void invoke();
}
}
public void testGetOptionsForDirectMappingWithStaticInitializer() {
Class[] classes = {
DirectMappingStatic.class,
DirectMappingStatic.DirectStructure.class,
DirectMappingStatic.DirectCallback.class,
};
for (int i=0;i < classes.length;i++) {
assertEquals("Wrong type mapper for direct mapping " + classes[i],
DirectMappingStatic.TEST_MAPPER, Native.getTypeMapper(classes[i]));
assertEquals("Wrong alignment for direct mapping " + classes[i],
DirectMappingStatic.TEST_ALIGNMENT, Native.getStructureAlignment(classes[i]));
assertEquals("Wrong encoding for direct mapping " + classes[i],
DirectMappingStatic.TEST_ENCODING, Native.getStringEncoding(classes[i]));
Object last = Native.getLibraryOptions(classes[i]);;
assertSame("Options not cached", last, Native.getLibraryOptions(classes[i]));
}
}
static class RemappedCLibrary {
public static native int $$YJP$$strlen(String s);
public static native int _prefixed_strlen(String s);
}
public void testDirectMappingFunctionMapper() {
FunctionMapper MAPPER = new FunctionMapper() {
public String getFunctionName(NativeLibrary lib, Method method) {
String name = method.getName();
if (name.startsWith("_prefixed_")) {
return name.substring(10);
}
return name;
}
};
Map options = new HashMap();
options.put(Library.OPTION_FUNCTION_MAPPER, MAPPER);
try {
Native.register(RemappedCLibrary.class,
NativeLibrary.getInstance(Platform.C_LIBRARY_NAME, options));
final String VALUE = getName();
int len;
len = RemappedCLibrary.$$YJP$$strlen(VALUE);
assertEquals(VALUE.length(), len);
len = RemappedCLibrary._prefixed_strlen(VALUE);
assertEquals(VALUE.length(), len);
}
catch(Exception e) {
fail("Native method was not properly mapped: " + e);
}
}
}

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais