Comparar commits

...

155 Commits

Autor SHA1 Mensagem Data
Wayne Meissner 130885fda7 3.0.9 release
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@739 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-30 20:22:28 +00:00
Wayne Meissner c4fc42f8f4 Bump version to 3.0.9 and update release-notes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@738 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-30 20:17:14 +00:00
Wayne Meissner 21e73c5fb9 Fix for issue #93 and JRUBY-3084.
This alters the library search algorithm slightly:
1) Searches jna.library.path and any custom (per-library) paths for a
   matching library.
2) If that fails, tries to load the mapped library name, using
   dlopen/LoadLibrary.
3) If that fails, add all paths back into the search path and try to locate
   the library in jna.platform.library.path with all the normal fallbacks.

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@737 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-29 00:30:54 +00:00
Wayne Meissner b635bf5591 Build 3.0.8
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@735 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-18 21:01:42 +00:00
Timothy Wall be594bb1f6 provide String->primitive array conversion
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@734 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-17 17:29:32 +00:00
Timothy Wall 543e3fca98 add more return types
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@733 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-15 02:56:51 +00:00
Wayne Meissner b385d76dc6 Add support for jna.boot.library.path property. This is a list of paths to attempt to load the jna stub library from. Its needed by JRuby and possibly Jython, to load the stub library from the file system, as they both put jna.jar in -Xbootclasspath, and java.library.path/LD_LIBRARY_PATH are ignored in that situation.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@732 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-12 06:02:31 +00:00
Timothy Wall 2adc88fec3 fix build of dependent test library on w32-x86
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@731 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-08 12:33:58 +00:00
Timothy Wall 2a9e2ceb61 support notes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@730 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-07 11:13:40 +00:00
Timothy Wall 47fa804469 bump version
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@728 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-01 13:44:23 +00:00
Timothy Wall f70c01eee7 fix broken link
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@727 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-01 13:37:10 +00:00
Timothy Wall eb4ea07a2d update win32 natives
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@726 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-10-01 13:37:01 +00:00
Timothy Wall 55cd72baaa Fix class cast exception
read all TYPE_MAPPERs regardless of access

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@725 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-29 12:20:56 +00:00
Timothy Wall 940076d101 update demo files
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@724 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-26 00:41:56 +00:00
Timothy Wall 93ebb9f7a9 improve win32 dependent library loading
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@723 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-22 15:55:59 +00:00
Timothy Wall 1a17ea52d8 add win64 target
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@718 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-17 18:14:49 +00:00
Timothy Wall 68bc0c0c7c add win64 target
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@717 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-17 18:09:40 +00:00
Timothy Wall 0e7dd6b350 note Memory vs primitive array usage
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@716 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-17 12:21:23 +00:00
Timothy Wall b3b0bf3845 note Memory vs primitive array usage
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@715 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-17 12:17:58 +00:00
Timothy Wall ddc32f1e43 update main page
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@714 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-16 18:25:25 +00:00
Timothy Wall c9de508a2c 3.0.6 build
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@712 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-16 18:15:53 +00:00
Timothy Wall fac68bca4e update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@711 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-14 20:11:57 +00:00
Timothy Wall eaf250c3c6 struct/union improvements
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@710 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-12 14:05:07 +00:00
Timothy Wall 8b99772d29 clean up field type checking
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@709 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-11 18:34:54 +00:00
Timothy Wall 862a32e97e Fix pointer field read bug
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@708 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-11 17:23:48 +00:00
Timothy Wall 6cfb84d6ee more mingw-64 fixes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@707 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-11 14:01:49 +00:00
xylo 2fda7ca6f6 in Union: added methods getTypedValue() and setTypedValue() as abridgment for the commands u.setType(), u.read(), x = u.field; also added corresonding tests to class UnionTest
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@706 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-11 05:48:17 +00:00
Timothy Wall f2aecb53bc fix configure/build with mingw-64 (tests still fail)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@705 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-11 03:19:41 +00:00
Timothy Wall 05fdc2f17a update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@704 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-10 17:21:11 +00:00
xylo b9868b993c take X11 from x11-addons branch
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@703 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-10 17:16:22 +00:00
Wayne Meissner 573d8eefd1 Updated i386-OpenBSD build
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@702 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-10 15:28:33 +00:00
Timothy Wall 51d64f29e6 clean up some libffi bits
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@700 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-09 15:08:58 +00:00
Timothy Wall a39ab60ae5 update natives
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@698 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 15:30:23 +00:00
Timothy Wall ba9671fae5 update natives
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@697 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 15:21:04 +00:00
Timothy Wall a9340f354d update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@696 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 14:59:09 +00:00
Timothy Wall f9d6b069f7 update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@695 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 14:50:59 +00:00
Timothy Wall c363d5790d update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@694 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 14:38:54 +00:00
Timothy Wall 15a50d2a26 update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@693 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 14:29:43 +00:00
Timothy Wall bffc188151 bump revision
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@692 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 13:06:41 +00:00
Timothy Wall e78205430c update native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@691 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 13:05:23 +00:00
Timothy Wall 4ef76d4f85 Allow arbitrary callback method names
Allow specification of callback type mapper with TYPE_MAPPER
Allow write with uninitialized boxed primitives in Structure
Fix memory leak with callbacks called from native threads w/no java context
Fix Structure derived classes to allow setting TypeMapper

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@690 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-08 12:56:04 +00:00
Timothy Wall 967da46793 Fix memory leak in callbacks
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@689 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-07 17:32:02 +00:00
xylo 46899503bd take X11 from x11-addons branch
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@686 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-06 17:24:37 +00:00
Timothy Wall 2dcf0f774c add win64 note
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@685 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-04 15:34:24 +00:00
Timothy Wall d669db0cab update jars with win64 build
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@684 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-04 15:29:52 +00:00
Timothy Wall f8aabcc50a merge win64 branch
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@683 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-04 15:04:34 +00:00
Timothy Wall 4bb3ece8dc Fix transparent window error on win2k
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@669 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-09-01 19:33:56 +00:00
Timothy Wall 495a7765d2 include LICENSE.txt in src.zip
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@648 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-26 13:39:46 +00:00
Timothy Wall 225296f253 avoid more content dragging on OSX, or warn
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@647 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-22 14:35:27 +00:00
Timothy Wall 52e6900e7a fix typo
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@645 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-14 14:56:01 +00:00
Timothy Wall 557bff1465 update doc
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@644 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-14 14:53:14 +00:00
Timothy Wall add32ac107 bump version
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@643 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-14 14:52:56 +00:00
Timothy Wall f7699b98fb release 3.0.5
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@641 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-14 14:47:41 +00:00
Timothy Wall 05a8ec1fec add java.net maven repo plumbing
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@640 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-14 14:33:01 +00:00
Timothy Wall 004e63c433 allow String[] as callback argument/return
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@639 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-13 14:17:40 +00:00
Timothy Wall 898f41b95a avoid reallocating Integer objects
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@638 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-13 13:51:59 +00:00
Timothy Wall 859a6a75aa apply patch #81
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@637 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-09 12:10:11 +00:00
Timothy Wall b90dae6448 add sunos-sparc build compatible with solaris 8
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@636 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-08 04:45:14 +00:00
Timothy Wall dc1ddf4cff add usb for java
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@635 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-08 04:37:37 +00:00
Timothy Wall 46ef5d86c3 add usb for java
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@634 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-08 04:36:27 +00:00
Timothy Wall ac63a6b125 fix field access
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@633 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-07 12:25:26 +00:00
Timothy Wall 72778c97df Allow explicit setting of structure field order
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@632 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-07 11:11:07 +00:00
Timothy Wall b4b86081f9 address issue #79, optionally omit jnilib
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@631 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-08-05 17:16:02 +00:00
Timothy Wall e4a47a4ca5 update relnotes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@630 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-31 16:17:51 +00:00
Timothy Wall 79c60f6d4e Fix cursor tracking on alpha-masked windows
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@629 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-31 16:17:10 +00:00
Timothy Wall 4c4d55e0dc add backup in case pkg-config fails
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@628 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-31 16:03:24 +00:00
Timothy Wall 9504416beb Allow link against system libffi with 'ant -Ddynlink.native=true'
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@627 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-29 14:55:59 +00:00
Timothy Wall 99586d9b3f Provide src.zip for linux builds, old version now src-full.zip
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@626 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-29 13:50:45 +00:00
Timothy Wall 65b19cbbd3 Fix 32/64-bit library lookup where both arch versions exist
Try 'lib' prefix on w32

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@625 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-29 00:00:40 +00:00
Wayne Meissner 7b64f4443d More OpenBSD build changes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@624 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-26 05:49:53 +00:00
Wayne Meissner abb2e857be Revert md5 sum now that OpenBSD is fixed up
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@623 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-26 05:47:47 +00:00
Wayne Meissner df10745963 Use ggrep for OpenBSD. Not strictly correct, but grep -A1 on OpenBSD does not print out a '--' separator between matches. Strangely, -B1 does ...
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@622 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-26 05:47:30 +00:00
Wayne Meissner 3d729595d1 i386-OpenBSD port
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@621 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-26 05:47:12 +00:00
Timothy Wall 96a38d1895 Fix division by zero on OSX/ppc calculating struct size
Fix overwriting of already-initialized NativeMapped field in struct when calculating struct size

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@620 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-13 18:53:49 +00:00
Timothy Wall b4c1390af8 Work around OSX transparent window dragging bug
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@619 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-08 14:32:52 +00:00
Timothy Wall e9604ac212 update to 3.0.4
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@617 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-05 18:55:32 +00:00
Timothy Wall ea3a4b34ea update javadoc
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@616 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-05 12:17:08 +00:00
Timothy Wall 79a0d92161 update javadoc
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@615 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-05 12:16:07 +00:00
Timothy Wall b10c40260c enable NativeMapped array fields in Structure read/write
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@614 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-03 19:33:25 +00:00
xylo 9e056d2097 in StructureTest.testReadWriteStructure: test constancy of references after reading structure from memory
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@610 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-03 09:49:08 +00:00
Timothy Wall 8a250c5994 Look up proper library on Linux where arch=x86_64
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@607 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-07-01 14:17:56 +00:00
xylo e311ac3269 in StructureTest.testReadWriteStructure: tabs replaced by spaces
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@604 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-28 14:03:24 +00:00
xylo 28078a2d0c in StructureTest.testReadWriteStructure: compare content of arrays after write/read structure
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@603 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-28 13:51:43 +00:00
xylo 7def8c1bbf in X11: remove tailing spaces in comments
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@602 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-28 12:11:26 +00:00
xylo 24ca11387e in Pointer: remove unnecessary spaces in comments
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@601 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-28 12:05:29 +00:00
xylo bccc9583c1 in X11: return Atom constants when calling Atom.fromNative(...)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@600 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-28 08:42:26 +00:00
xylo 9643747b17 in X11: added some native functions
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@599 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-27 17:51:45 +00:00
xylo c695848092 in X11: added remaining Atom constants (from 9 to 68)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@595 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-26 18:49:52 +00:00
Dan Rollo 5011613e4c Add GetDriveType() to Kernerl32 examples. Patch by Marc Strapetz.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@585 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-24 03:18:22 +00:00
Timothy Wall 6cc7f69a59 Make X11.XID NativeLong
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@583 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-23 22:48:37 +00:00
Timothy Wall db6678637b Ensure struct allocated when calling Union.setType
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@582 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-23 22:47:19 +00:00
Timothy Wall 93892e12a2 Fix incorrect solaris/x86 native library
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@581 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-23 19:01:07 +00:00
Timothy Wall c196aab89d remove trailing comment close
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@580 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-22 12:04:07 +00:00
Timothy Wall 54a7718b88 clean up X headers
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@579 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-22 12:03:20 +00:00
Timothy Wall cec6e6175a Use the actual parameter type in Function invocations if no paramter type information is available (whether method is missing or untyped varargs).
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@578 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-22 11:30:57 +00:00
Timothy Wall bc5036bd34 auto-write Structure.ByReference fields
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@577 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-21 21:00:37 +00:00
Timothy Wall 021826eb1b update release notes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@576 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-21 20:42:23 +00:00
Timothy Wall facd071967 Handle arrays of NativeMapped in Structure fields
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@575 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-06-21 20:40:33 +00:00
Timothy Wall 486e81ad77 upgrade to 2.x clover
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@574 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-29 14:42:11 +00:00
Timothy Wall 872cd3d7c0 Apply xylo's library load patch, fix versioned name checking tests
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@573 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-27 13:59:06 +00:00
Timothy Wall ca9851b311 Fix linux library load bug
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@572 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-23 14:22:08 +00:00
Timothy Wall 2fa0940d45 update jna.jar with updated linux builds
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@569 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 20:48:04 +00:00
Timothy Wall 3485338386 update linux-amd64 to 3.0.4 (native)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@568 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 20:33:43 +00:00
Timothy Wall 786a821f3f update linux-i386 jar to 3.0.4 (native)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@567 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 20:30:19 +00:00
Timothy Wall da1c9c5ea5 remove erroneous comment
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@565 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 17:04:23 +00:00
Timothy Wall 93d8cce7ac post 3.0.3 build
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@564 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 17:03:51 +00:00
Timothy Wall 5086ba2a3b include project files in source zip
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@563 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-22 16:32:12 +00:00
Timothy Wall 4cf8611dcd add note
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@562 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-20 15:42:41 +00:00
Timothy Wall 101e9d705a Add more win32 type examples
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@561 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-20 15:10:57 +00:00
Timothy Wall 7d8bfa1b62 Fix NPE in NativeMappedConverter
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@560 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-20 15:09:48 +00:00
Timothy Wall 5dcf9e2f41 update perf info
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@559 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-14 14:49:13 +00:00
Timothy Wall cdf18b6c4d ensure memory is initialized before Structure.read() - avoid NPE
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@558 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-09 15:21:55 +00:00
Timothy Wall 609ce3b6e0 ensure memory is initialized before Structure.read() - avoid NPE
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@557 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-09 15:21:05 +00:00
Timothy Wall 3ba8be2e21 improve package/version information in code and manifest
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@556 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-05 23:58:48 +00:00
Timothy Wall 6b13a97ce4 fix jnlp links
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@555 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-02 20:49:20 +00:00
Dan Rollo 130e40957e Fix issue# 68 - File monitor thread terminates on any removeWatch call.
kludge: fix intermittent failures on slow W2K box.

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@554 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-02 03:56:38 +00:00
Dan Rollo a7b28317d7 Fix issue# 68 - File monitor thread terminates on any removeWatch call. Change W32FileMonitor.dispose() to unwatch any remaining files in map, allows watcher thread to exit.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@553 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-02 03:29:13 +00:00
Dan Rollo 29fcd0fdcf Fix issue# 68 - File monitor thread terminates on any removeWatch call. (only formatting and debug info changes)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@552 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-02 02:04:58 +00:00
Dan Rollo 9d5f63e543 Fix issue# 68 - File monitor thread terminates on any removeWatch call.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@551 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-02 01:20:59 +00:00
Timothy Wall 208c28ead2 add entry for native long mapping
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@550 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-05-01 15:16:55 +00:00
Timothy Wall 447d5ee94b Allow 'final' modifier in Structure fields
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@549 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-25 13:43:06 +00:00
Dan Rollo bb443add17 Fix for Jira issue: 67 - FileMonitor incorrectly handles FILE_DELETED notification mask. Added a unit test and committed fix.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@548 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-24 03:33:39 +00:00
Timothy Wall cb954773ed Fix bug in ByValue structs using NativeMapped
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@547 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-15 16:51:35 +00:00
Timothy Wall 89749c7eb1 update native builds
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@546 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-11 20:22:06 +00:00
Timothy Wall 30146f8744 fix callback allocation on freebsd
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@545 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-11 19:48:27 +00:00
Timothy Wall a623f374b1 enable mmap closures on solaris
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@544 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-11 18:33:17 +00:00
Dan Rollo b41584feb3 fix test failures on amd64 with 64-bit jvm. Classloader/path was using "build" instead of "build-d64".
NOTE: I considered changing and re-using the ["vmopt.arch" value="-d64" else="-Dignore"] already defined in build.xml for this, but I wasn't sure what the "-Dignore" case was intended for.

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@543 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-11 07:34:41 +00:00
Timothy Wall 77d5bbb767 Fix typo
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@542 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-11 01:55:21 +00:00
Timothy Wall 171d428d3a Improve StdCallFunctionMapper
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@541 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-10 14:35:35 +00:00
Timothy Wall 61254c6cc4 Fix callbacks when DEP is enabled
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@540 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-10 02:39:51 +00:00
Timothy Wall 44b3a8952e fix typos
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@539 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-08 17:54:21 +00:00
Timothy Wall 0fc8c5e7e9 add videolan project
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@538 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-08 12:45:16 +00:00
Timothy Wall 6d969eb92f improve X11 window masking performance
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@537 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-08 09:29:02 +00:00
Timothy Wall 26ea0f81ca only set vm arch option for 64-bit vms
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@536 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-03 15:19:43 +00:00
Timothy Wall dc45e38f11 fix relocation errors on sunos-amd64
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@535 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-03 14:40:42 +00:00
Timothy Wall 9d5db40d3f enable ibm j9 build/run
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@534 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-03 00:57:47 +00:00
Timothy Wall 9e25d52679 improve w32 window masking
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@533 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-01 16:09:56 +00:00
Timothy Wall 1f98d4f6ff improve performance of window masking
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@532 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-04-01 00:59:12 +00:00
Timothy Wall b73883ce1d Refine test for IBM's J9 VM
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@531 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-31 14:26:32 +00:00
Timothy Wall 7af42da5d2 partial fix for aix/ppc
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@530 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-31 13:18:29 +00:00
Timothy Wall cf75057b67 fix bug where struct is incorrectly passed by value instead of by reference
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@529 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-13 17:27:15 +00:00
Timothy Wall e5b1841030 Check entire linux version, not just last digit
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@528 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-11 04:48:27 +00:00
Dan Rollo 57325a22a5 refactor common code
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@527 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-09 05:31:48 +00:00
Dan Rollo c640166cf8 remove unused import, make unchanging member vars final.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@526 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-09 05:19:14 +00:00
Dan Rollo 4b4c362c03 remove unused imports
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@525 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-09 05:15:47 +00:00
Dan Rollo c71bfb1602 fix testMultipleWatches() by clearing prior events.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@524 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-09 00:43:35 +00:00
Dan Rollo 022e6349c1 make Kernel32/Test work on Win2k.
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@523 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-09 00:42:00 +00:00
Timothy Wall 917671ac9a use frames link for javadoc
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@522 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-07 15:29:24 +00:00
Timothy Wall a108975d78 link to javadoc sans dev.java.net navigation
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@521 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-07 15:28:22 +00:00
Timothy Wall 62d31c5902 Fix NPE
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@520 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-04 16:28:36 +00:00
Timothy Wall 5d28314ee3 Add Emmanuel's Lego Mindstorm NXT driver
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@519 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-01 12:41:26 +00:00
Timothy Wall 1b22109f95 update platform list, support notes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@518 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-03-01 12:35:53 +00:00
Timothy Wall e5c05bfd66 fix constant usage
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@517 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-29 16:07:38 +00:00
Timothy Wall 62e97858d7 tweak main page
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@516 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-29 15:54:56 +00:00
Timothy Wall b9da9b977e tweak main page
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@515 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-29 15:54:09 +00:00
352 arquivos alterados com 115454 adições e 80235 exclusões
+7
Ver Arquivo
@@ -22,6 +22,13 @@
# TODO
* pointer.setValue(), to handle NativeMapped types and move read/writeValue
methods out of Structure, to be used by Function w/NativeMapped[] parameter
* write structure to contiguous Java array, then write all at once to minimize
native calls. Otherwise, structs with lots of fields take a big performance
hit making a native call for each field.
* parser (gluegen? swig? others?) to auto-generate JNA interfaces from headers;
ideally get the native library build system to output preprocessed headers,
otherwise CPP crap is a nightmare to get right.
+106 -50
Ver Arquivo
@@ -17,6 +17,8 @@
<property name="jar" value="${name}.jar"/>
<property name="debug" value="true"/>
<property name="debug.native" value="false"/>
<property name="cflags_extra.native" value=""/>
<property name="dynlink.native" value="false"/>
<property name="native" location="native"/>
<property name="src" location="src"/>
<property name="dist" location="dist"/>
@@ -26,25 +28,25 @@
<property name="stylesheet" location="${javadoc}/doc/css/javadoc.css"/>
<property name="vendor" value="JNA Development Team"/>
<property name="copyright"
value="Copyright &amp;copy; 2007 Timothy Wall. All Rights Reserved."/>
value="Copyright &amp;copy; 2007-2008 Timothy Wall. All Rights Reserved."/>
<buildnumber/>
<!-- JNA library release version -->
<property name="jna.major" value="3"/>
<property name="jna.minor" value="0"/>
<property name="jna.revision" value="2"/>
<property name="jna.revision" value="9"/>
<property name="jna.build" value="${build.number}"/>
<property name="jna.version" value="${jna.major}.${jna.minor}.${jna.revision}"/>
<!-- jnidispatch library release version -->
<property name="jni.major" value="3"/>
<property name="jni.minor" value="0"/>
<property name="jni.revision" value="3"/>
<property name="jni.revision" value="6"/>
<property name="jni.build" value="${build.number}"/>
<property name="jni.version" value="${jni.major}.${jni.minor}.${jni.revision}"/>
<property name="jni.md5" value="892beacd437514d23ed9b1cefeb2ead6"/>
<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="${spec.title}"/>
<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}"/>
@@ -64,7 +66,24 @@
<target name="-dynamic-properties">
<echo>Java version: ${java.version}, compatibility: ${compatibility}</echo>
<echo>JNA version ${jna.version}, native API version ${jni.version}</echo>
<property name="build" value="build"/>
<replaceregexp match="(&lt;version&gt;).*(&lt;/version&gt;)"
replace="\1${jna.version}\2"
file="pom.xml"/>
<condition property="jar.omitted" value="**/*jnidispatch*" else="jnilib-included">
<isset property="omit-jnilib"/>
</condition>
<condition property="vm.arch" value="-d64" else="">
<or>
<equals arg1="${sun.arch.data.model}" arg2="64" trim="true"/>
<os arch="x86_64"/>
<os arch="ppc64"/>
<os arch="sparcv9"/>
<os arch="amd64"/>
</or>
</condition>
<property name="build" value="build${vm.arch}"/>
<property name="classes" location="${build}/classes"/>
<property name="eclipse.classes" location="build.eclipse/classes"/>
<property name="test.classes" location="${build}/test-classes"/>
@@ -74,6 +93,14 @@
<condition property="os.prefix" value="win32-${os.arch}">
<os family="windows"/>
</condition>
<condition property="os.prefix" value="linux-i386">
<!-- IBM's J9 reports 'x86' -->
<and><os name="Linux"/><os arch="x86"/></and>
</condition>
<condition property="os.prefix" value="linux-amd64">
<!-- Debian reports 'x86_64' -->
<and><os name="Linux"/><os arch="x86_64"/></and>
</condition>
<condition property="os.prefix" value="linux-${os.arch}">
<os name="Linux"/>
</condition>
@@ -87,6 +114,9 @@
<condition property="os.prefix" value="freebsd-${os.arch}">
<os name="FreeBSD"/>
</condition>
<condition property="os.prefix" value="openbsd-${os.arch}">
<os name="OpenBSD"/>
</condition>
<fail unless="os.prefix" message="OS/arch not supported (${os.name}/${os.arch}), edit build.xml and native/Makefile to add it."/>
<condition property="jdk.home" value="${java.home}">
<available file="${java.home}/include"/>
@@ -129,7 +159,7 @@
<pathelement path="${build}/${jar}"/>
<pathelement path="${build}/examples.jar"/>
<pathelement path="${test.classes}"/>
<pathelement path="${ant.home}/lib/clover.jar"/>
<pathelement path="lib/clover.jar"/>
<path refid="test.libs"/>
</path>
</target>
@@ -161,15 +191,19 @@
description="Build primary jar">
<jar jarfile="${build}/${jar}">
<manifest>
<attribute name="Implementation-Title" value="${impl.title}"/>
<attribute name="Implementation-Vendor" value="${vendor}"/>
<attribute name="Implementation-Version" value="${impl.version}"/>
<attribute name="Specification-Title" value="${spec.title}"/>
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
<attribute name="Specification-Version" value="${spec.version}"/>
<attribute name="Main-Class" value="com.sun.jna.Native"/>
<section name="com/sun/jna/">
<attribute name="Implementation-Title" value="${impl.title}"/>
<attribute name="Implementation-Vendor" value="${vendor}"/>
<attribute name="Implementation-Version" value="${impl.version}"/>
<attribute name="Specification-Title" value="${spec.title}"/>
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
<attribute name="Specification-Version" value="${spec.version}"/>
</section>
</manifest>
<fileset dir="${classes}"><patternset refid="jar-compiled"/></fileset>
<fileset dir="${classes}" excludes="${jar.omitted}">
<patternset refid="jar-compiled"/>
</fileset>
</jar>
</target>
<target name="examples" depends="jar,native">
@@ -196,6 +230,9 @@
<condition property="grep" value="/usr/sfw/bin/ggrep">
<os name="SunOS"/>
</condition>
<condition property="grep" value="ggrep">
<os name="OpenBSD"/>
</condition>
<property name="grep" value="grep"/>
<apply dir="${build.native}" executable="${grep}" parallel="true"
failonerror="true" relative="true" output="${md5.file}">
@@ -216,10 +253,12 @@
<echo>Invalidating native code, new checksum is ${md5}</echo>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/darwin.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/win32-x86.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/win32-amd64.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/linux-i386.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/linux-amd64.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/freebsd-i386.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/freebsd-amd64.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/openbsd-i386.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-x86.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-amd64.jar" overwrite="true"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-sparc.jar" overwrite="true"/>
@@ -267,12 +306,7 @@
file="native/Makefile" byline="true"/>
<!-- ensure ARCH is set properly for 64-bit capable platforms -->
<!-- use ANT_OPTS=-d64 to build 64-bit if not the platform default -->
<condition property="ARCH" value="${os.arch}">
<or>
<os arch="sparcv9"/>
<os arch="amd64"/>
</or>
</condition>
<property name="ARCH" value="${os.arch}"/>
<condition property="make.CC" value="CC=${CC}" else="IGNORE=">
<isset property="CC"/>
</condition>
@@ -302,7 +336,10 @@
<os name="SunOS"/>
</condition>
<condition property="make" value="gmake">
<os name="FreeBSD"/>
<or>
<os name="FreeBSD"/>
<os name="OpenBSD"/>
</or>
</condition>
<!-- Default make program -->
<property name="make" value="make"/>
@@ -311,6 +348,8 @@
<arg value="JAVA_HOME=${jdk.home}"/>
<arg value="JAVAH=${build.native}"/>
<arg value="DEBUG=${debug.native}"/>
<arg value="CFLAGS_EXTRA=${cflags_extra.native}"/>
<arg value="DYNAMIC_LIBFFI=${dynlink.native}"/>
<arg value="${make.CC}"/>
<arg value="${make.BUILD}"/>
<arg value="${make.SDKROOT}"/>
@@ -321,13 +360,13 @@
</exec>
<mkdir dir="${classes}/com/sun/jna/${os.prefix}"/>
<copy todir="${classes}/com/sun/jna/${os.prefix}">
<fileset dir="${build.native}"
<fileset dir="${build.native}"
includes="jnidispatch.dll,libjnidispatch.*"/>
</copy>
<mkdir dir="${eclipse.classes}/com/sun/jna/${os.prefix}"/>
<copy todir="${eclipse.classes}/com/sun/jna/${os.prefix}"
failonerror="false">
<fileset dir="${build.native}"
<fileset dir="${build.native}"
includes="jnidispatch.dll,libjnidispatch.*"/>
</copy>
<!-- For web start, native libraries may be provided in the root of -->
@@ -353,7 +392,7 @@
</target>
<!-- When running tests from an IDE, be sure to set jna.library.path -->
<!-- to where the test library (testlib) is found -->
<!-- to where the test library (testlib) is found. -->
<target name="test" depends="jar,examples,compile-tests"
description="Run all unit tests">
<property name="test.fork" value="yes"/>
@@ -361,28 +400,34 @@
<property name="results.junit" location="${build}/junit-results"/>
<mkdir dir="${results.junit}"/>
<echo>Saving test results in ${results.junit}</echo>
<property name="tests.stdcall" value="**/win32/*StdCallTest.java"/>
<condition property="tests.platform" value="**/win32/*Test.java">
<os family="windows"/>
</condition>
<condition property="tests.exclude" value="**/win32/*StdCallTest.java">
<and><os family="windows"/><not><os arch="x86"/></not></and>
</condition>
<condition property="tests.platform" value="**/unix/*Test.java">
<and>
<os family="unix"/>
<not><os family="mac"/></not>
</and>
</condition>
<condition property="vm.arch" value="-d64">
<or>
<and><os family="mac"/>
<or><os arch="x86_64"/><os arch="ppc64"/></or>
</and>
<os arch="sparcv9"/>
</or>
<condition property="vmopt.arch" value="-d64" else="-Dignore">
<and>
<!-- Sun 64-bit VM for windows doesn't support the -d64 switch -->
<not><os family="windows"/></not>
<equals arg1="${vm.arch}" arg2="-d64" trim="true"/>
</and>
</condition>
<property name="vm.arch" value="-Dignore"/>
<property name="tests.platform" value=""/>
<property name="tests.exclude" value=""/>
<junit printsummary="yes" fork="${test.fork}" failureproperty="testfailure">
<jvmarg value="-Djna.library.path=${build.native}"/>
<jvmarg value="${vm.arch}"/>
<!-- Avoid VM crashes, if possible -->
<jvmarg value="-Djna.protected=true"/>
<jvmarg value="-Djna.builddir=${build}"/>
<jvmarg value="${vmopt.arch}"/>
<classpath><path refid="test.runpath"/></classpath>
<formatter type="xml"/>
<batchtest todir="${results.junit}">
@@ -405,18 +450,10 @@
</target>
<target name="with.clover" description="Enable code coverage for tests">
<taskdef resource="clovertasks"/>
<taskdef resource="cloverlib.xml" classpath="lib/clover.jar"/>
<property name="clover" value="true"/>
<property name="build" value="build.clover"/>
<property name="clover.include" value="**/*.java"/>
<property name="clover.exclude" value="**/examples/**/*.java"/>
<property name="tests.exclude" value="${clover.exclude}"/>
<clover-setup initString="${build}/coverage.db">
<fileset dir="${src}">
<include name="${clover.include}"/>
<exclude name="${clover.exclude}"/>
</fileset>
</clover-setup>
<clover-setup/>
</target>
<target name="clover" depends="with.clover,test"
@@ -425,6 +462,8 @@
<mkdir dir="${reports.clover}"/>
<clover-report>
<current outfile="${reports.clover}" title="clover">
<fileset dir="." includes="**/*.java" excludes="**/examples/**/*.java"/>
<testresults dir="${results.junit}" includes="TEST-*.xml"/>
<format type="html"/>
</current>
</clover-report>
@@ -471,13 +510,15 @@
description="Build distribution files">
<jar jarfile="${dist}/jna.jar" duplicate="preserve">
<manifest>
<attribute name="Implementation-Title" value="${impl.title}"/>
<attribute name="Implementation-Vendor" value="${vendor}"/>
<attribute name="Implementation-Version" value="${impl.version}"/>
<attribute name="Specification-Title" value="${spec.title}"/>
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
<attribute name="Specification-Version" value="${spec.version}"/>
<attribute name="Main-Class" value="com.sun.jna.Native"/>
<section name="com/sun/jna/">
<attribute name="Implementation-Title" value="${impl.title}"/>
<attribute name="Implementation-Vendor" value="${vendor}"/>
<attribute name="Implementation-Version" value="${impl.version}"/>
<attribute name="Specification-Title" value="${spec.title}"/>
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
<attribute name="Specification-Version" value="${spec.version}"/>
</section>
</manifest>
<zipfileset src="${build}/${jar}"/>
<zipfileset src="${dist}/win32-x86.jar"
@@ -510,6 +551,12 @@
<zipfileset src="${dist}/freebsd-amd64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/freebsd-amd64"/>
<zipfileset src="${dist}/openbsd-i386.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/openbsd-i386"/>
<zipfileset src="${dist}/win32-amd64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/win32-amd64"/>
</jar>
<copy todir="${dist}">
<fileset dir="${build}">
@@ -520,11 +567,20 @@
<zip zipfile="${dist}/doc.zip">
<zipfileset dir="${javadoc}" prefix="javadoc"/>
</zip>
<!-- JNA sources only, for use in Linux build from source -->
<zip zipfile="${dist}/src.zip">
<zipfileset dir="." includes="build.xml"/>
<zipfileset dir="." includes="build.xml,LICENSE.txt"/>
<zipfileset dir="${src}" includes="**/*.java" prefix="src"/>
<zipfileset dir="${test.src}" includes="**/*.java" prefix="test"/>
<zipfileset dir="${native}" prefix="native"/>
<zipfileset dir="${native}" excludes="libffi,libffi/**/*" prefix="native"/>
</zip>
<!-- Full sources required to build and test everything -->
<zip zipfile="${dist}/src-full.zip">
<zipfileset src="${dist}/src.zip"/>
<zipfileset dir="lib" includes="junit.jar" prefix="lib"/>
<zipfileset dir="." includes=".classpath,.project"/>
<zipfileset dir="nbproject" includes="**/*" prefix="nbproject"/>
<zipfileset dir="${native}" includes="libffi,libffi/**/*" prefix="native"/>
</zip>
</target>
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.
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.
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.
externo Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
+5
Ver Arquivo
@@ -0,0 +1,5 @@
nQMpVtdkeiLDhkfVhlebsGWVMnsDeqDAmHuaUJSRUxwraf
mi2K4SaejnjOrPDIm3nJq8<b2Ke>wQwCu3>RYeCLGxFda>
PRoQxwONRmmnMpmQRPQvuNmQoQpMQRMpOnSSTxXMvwWmvu
VtqwVvXwqqRnmqmUUnnvuvvqqmmmmmUUnnvuvvqqmmmmmU
UgkXkabskgXsXkkbqUUnmm
+90 -52
Ver Arquivo
@@ -10,10 +10,10 @@
# Supported platforms (built and tested):
#
# Windows 2000/XP/2003/Vista (x86)
# OS X (i386/ppc)
# Linux (i386, amd64)
# Solaris (i386, sparc, sparcv9)
# FreeBSD (i386)
# Darwin/OS X (i386/x86_64/ppc)
# Linux (i386/amd64)
# Solaris (i386/amd64/sparc/sparcv9)
# FreeBSD (i386/amd64)
#
# Systems which support POSIX signals may be able to support VM crash
@@ -23,34 +23,40 @@
OS=$(shell uname | sed -e 's/\(CYGWIN\|MINGW32\).*/win32/g' \
-e 's/SunOS.*/solaris/g' \
-e 's/FreeBSD.*/freebsd/g' \
-e 's/OpenBSD.*/openbsd/g' \
-e 's/Darwin.*/darwin/g' \
-e 's/Linux.*/linux/g')
VERSION=3.0.3 # auto-generated by ant
VERSION=3.0.6 # auto-generated by ant
CHECKSUM=892beacd437514d23ed9b1cefeb2ead6 # auto-generated by ant
JAVA_INCLUDES=-I"$(JAVA_HOME)/include" \
-I"$(JAVA_HOME)/include/$(OS)"
LIBDIR=$(JAVA_HOME)/jre/lib/$(ARCH)
BUILD=../build/native
JAVAH=$(BUILD)
INSTALLDIR=../build/$(OS)
JNIDISPATCH_OBJS=$(BUILD)/dispatch.o $(BUILD)/callback.o $(EXTRAOBJS)
RSRC=$(BUILD)/rsrc.o
ifneq ($(DYNAMIC_LIBFFI),true)
FFI_SRC=$(shell pwd)/libffi
FFI_BUILD=$(BUILD)/libffi
FFI_LIB=$(FFI_BUILD)/.libs/libffi_convenience.a
FFI_CONFIG=--disable-static --with-pic=yes
FFI_LIB=$(FFI_BUILD)/.libs/libffi$(ARSFX)
FFI_ENV=CC="$(CC)" CFLAGS="$(CDEBUG)" CPPFLAGS="$(CDEFINES)"
FFI_CONFIG=--enable-static --disable-shared --with-pic=yes
endif
LIBRARY=$(BUILD)/$(LIBPFX)jnidispatch$(JNISFX)
TESTLIB=$(BUILD)/$(LIBPFX)testlib$(LIBSFX)
TESTLIB2=$(BUILD)/$(LIBPFX)testlib2$(LIBSFX)
# Reasonable defaults based on GCC
LIBPFX=lib
LIBSFX=.so
ARSFX=.a
JNISFX=$(LIBSFX)
CC=gcc
LD=gcc
LIBS=
# Default to Sun recommendations for JNI compilation
#COPT=-O2 -fomit-frame-pointer
COPT=-fno-omit-frame-pointer -fno-strict-aliasing
@@ -58,14 +64,21 @@ CASM=-S
ifeq ($(DEBUG),true)
CDEBUG=-g
endif
CFLAGS_EXTRA=
COUT=-o $@
CINCLUDES=$(JAVA_INCLUDES) -I"$(JAVAH)" -I$(FFI_BUILD)/include
CDEFINES=-D_REENTRANT
PCFLAGS=-W -Wall -Wno-unused -Wno-parentheses
CFLAGS=$(PCFLAGS) $(COPT) $(CDEBUG) $(CDEFINES) $(CINCLUDES) \
CFLAGS=$(PCFLAGS) $(CFLAGS_EXTRA) $(COPT) $(CDEBUG) $(CDEFINES) $(CINCLUDES) \
-DVERSION='"$(VERSION)"' -DCHECKSUM='"$(CHECKSUM)"'
LDFLAGS=-o $@ -shared
ifeq ($(DYNAMIC_LIBFFI),true)
CFLAGS += $(shell pkg-config --cflags libffi 2>/dev/null || echo)
LIBS += $(shell pkg-config --libs libffi 2>/dev/null || echo -lffi)
else
# -static-libgcc avoids gcc library incompatibilities across linux systems
LDFLAGS=-o $@ -shared -Wl,-soname,$@ -static-libgcc
LDFLAGS += -static-libgcc
endif
# Avoid bug in X11-based 1.5/1.6 VMs; dynamically load instead of linking
# See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705
#LIBS=-L"$(LIBDIR)" -ljawt
@@ -73,51 +86,64 @@ STRIP=strip -x
# end defaults
ifeq ($(OS),win32)
# Uncomment this line to use MSVC (doesn't yet work with libffi)
#CC=cl
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
CDEFINES=-DHAVE_PROTECTION
ifeq ($(CC),cl)
LD=link
COPT=-O1 -Op
ifeq ($(DEBUG),true)
COPT=-Od
DBG=d
CDEBUG=-D_DEBUG -GZ -Zi
endif
COUT=-Fo$@
PCFLAGS=-nologo -MD$(DBG) -W3 -WX -GX -YX -Fd$(@D)/$* -Fp$(@D)/$*
CASM=-FAs
LDFLAGS=/pdb:$(subst .dll,,$@).pdb /implib:$(subst .dll,,$@).lib /debug /machine:i386 /pdbtype:sept /dll /nologo /opt:REF /incremental:no /out:$@
LIBDIR=/libpath:"$(JAVA_HOME)/lib"
#LIBS=$(LIBDIR) jawt.lib
WINDRES=windres
EXTRAOBJS=$(RSRC)
STRIP=@echo
else
PCFLAGS+=-mno-cygwin
LDFLAGS+=-mno-cygwin -Wl,--add-stdcall-alias
LIBDIR="$(JAVA_HOME)/lib"
#LIBS=$(LIBDIR)/jawt.lib
endif
LIBPFX=
LIBSFX=.dll
EXTRAOBJS=$(RSRC)
ifeq ($(CC),gcc)
CC += -mno-cygwin
LD += -mno-cygwin -Wl,--add-stdcall-alias
endif
ifeq ($(ARCH),amd64)
WINDRES=x86_64-pc-mingw32-windres
# Uncomment to enable MINGW64 cross compiler
# Last build attempt has too many runtime problems (alloca broken) (080831)
#MINGW = x86_64-pc-mingw32-gcc
ifneq ($(MINGW),)
CC = $(MINGW) -m64 -mno-cygwin
LD = $(CC)
LDFLAGS=-o $@ -shared
LIBS= -lmingwex -lkernel32 -lmsvcrt
FFI_CONFIG += --host=x86_64-pc-mingw32
else
# MSVC (wrapper scripts)
CC=$(FFI_SRC)/../cc.sh -m64
LD=$(FFI_SRC)/../ld.sh -m64
ARSFX=.lib
FFI_CONFIG += --host=x86_64-pc-mingw32 && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
FFI_ENV += LD="$(LD)" CPP=cpp
endif
endif
endif
ifeq ($(OS),linux)
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
PCFLAGS+=-fPIC
CDEFINES+=-DHAVE_PROTECTION
LDFLAGS+=-Wl,-soname,$@
endif
ifeq ($(OS),freebsd)
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
PCFLAGS+=-fPIC
CINCLUDES+=-I/usr/X11R6/include
LDFLAGS=-o $@ -shared
CDEFINES+=-DHAVE_PROTECTION
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
endif
ifeq ($(OS),openbsd)
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
endif
ifeq ($(OS),solaris)
@@ -125,21 +151,22 @@ ifeq ($(ARCH),)
ARCH=$(shell uname -p)
endif
PCFLAGS+=-fPIC
CDEFINES+=-DHAVE_PROTECTION
LDFLAGS=-o $@ -G
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
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
# choke
CC += -m64
LDFLAGS += -m64
LD += -m64
endif
endif
# Enable 64-bit builds if the arch demands it
ifeq ($(CC),gcc)
ifeq ($(ARCH),amd64)
CC += -m64
LDFLAGS += -m64
LD += -m64
endif
endif
ifeq ($(OS),darwin)
@@ -156,12 +183,12 @@ SYSLIBROOT=-Wl,-syslibroot,$(SDKROOT)
ISYSROOT=-isysroot $(SDKROOT)
ARCHFLAGS=-arch ppc -arch i386
ifneq ($(findstring 10.5,$(SDKROOT)),)
ALT_ARCHS+=x86_64 #ppc64
ARCHFLAGS+=-arch x86_64 #-arch ppc64
ALT_ARCHS+=x86_64
ARCHFLAGS+=-arch x86_64
endif
endif
PCFLAGS+=$(ISYSROOT) -x objective-c
CDEFINES=-DTARGET_RT_MAC_CFM=0
CDEFINES+=-DTARGET_RT_MAC_CFM=0 -DFFI_MMAP_EXEC_WRIT
LDFLAGS=$(ARCHFLAGS) -dynamiclib -o $@ -framework JavaVM \
-compatibility_version $(shell echo ${VERSION}|sed 's/^\([0-9][0-9]*\).*/\1/g') \
-current_version $(VERSION) \
@@ -187,27 +214,37 @@ else
$(CC) $(CFLAGS) -c $< $(COUT)
endif
all: $(LIBRARY) $(TESTLIB)
all: $(LIBRARY) $(TESTLIB) $(TESTLIB2)
install:
mkdir $(INSTALLDIR)
cp $(LIBRARY) $(INSTALLDIR)
$(RSRC): $(BUILD)/jnidispatch.rc
windres -i $< -o $@
$(WINDRES) -i $< -o $@ \
|| (echo > $@.c && $(CC) $(CFLAGS) -c $@.c $(COUT))
$(LIBRARY): $(JNIDISPATCH_OBJS) $(FFI_LIB)
$(LD) $(LDFLAGS) $(JNIDISPATCH_OBJS) $(FFI_LIB) $(LIBS)
$(TESTLIB): $(BUILD)/testlib.o
$(LD) $(LDFLAGS) $< $(TESTDEF)
$(LD) $(LDFLAGS) $<
ifeq ($(ARSFX),.lib)
TESTDEP=$(TESTLIB:.dll=.lib)
else
TESTDEP=$(TESTLIB)
endif
$(TESTLIB2): $(BUILD)/testlib2.o
$(LD) $(LDFLAGS) $< $(TESTDEP)
ifneq ($(DYNAMIC_LIBFFI),true)
$(FFI_LIB):
@mkdir -p $(FFI_BUILD)
@if [ ! -f $(FFI_BUILD)/Makefile ]; then \
echo "Configuring libffi ($(ARCH))"; \
(cd $(FFI_BUILD) \
&& CC="$(CC) $(CDEBUG)" $(FFI_SRC)/configure $(FFI_CONFIG)); \
&& $(FFI_ENV) $(FFI_SRC)/configure $(FFI_CONFIG)); \
fi
$(MAKE) -C $(FFI_BUILD)
ifneq ($(SDKROOT),)
@@ -216,7 +253,7 @@ ifneq ($(SDKROOT),)
if [ ! -f $(BUILD)/libffi.$$arch/Makefile ]; then \
echo "Configuring libffi ($$arch)"; \
(cd $(BUILD)/libffi.$$arch \
&& CFLAGS="-arch $$arch $(ISYSROOT) $(COPT) $(CDEBUG) $(CDEFINES)" \
&& CC="$(CC)" CFLAGS="-arch $$arch $(ISYSROOT) $(COPT) $(CDEBUG)" CPPFLAGS="$(CDEFINES)" \
LDFLAGS="-arch $$arch" \
$(FFI_SRC)/configure $(FFI_CONFIG) --host=$$arch-apple-darwin --disable-dependency-tracking); \
fi; \
@@ -225,6 +262,7 @@ ifneq ($(SDKROOT),)
/usr/bin/libtool -static -o $@.tmp $(FFI_BUILD)/.libs/${@F} $(BUILD)/libffi.*/.libs/${@F}
mv $@.tmp $@
endif
endif
clean:
$(RM) -rf $(BUILD)
+40 -23
Ver Arquivo
@@ -41,7 +41,6 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
callback* cb;
ffi_abi abi = FFI_DEFAULT_ABI;
ffi_status status;
int args_size = 0;
jsize argc;
JavaVM* vm;
char rtype;
@@ -64,13 +63,13 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
cb->param_jtypes[i] = get_jtype(env, cls);
cb->ffi_args[i] = get_ffi_type(env, cls, cb->param_jtypes[i]);
if (!cb->param_jtypes[i]) {
sprintf(msg, "Unsupported type at parameter %d", i);
snprintf(msg, sizeof(msg), "Unsupported type at parameter %d", i);
throwByName(env, EIllegalArgument, msg);
goto failure_cleanup;
}
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(_WIN64)
if (calling_convention == CALLCONV_STDCALL) {
abi = FFI_STDCALL;
}
@@ -86,25 +85,30 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
&cb->ffi_args[0]);
switch(status) {
case FFI_BAD_ABI:
sprintf(msg, "Invalid calling convention: %d", (int)calling_convention);
snprintf(msg, sizeof(msg),
"Invalid calling convention: %d", (int)calling_convention);
throwByName(env, EIllegalArgument, msg);
break;
case FFI_BAD_TYPEDEF:
sprintf(msg, "Invalid structure definition (native typedef error)");
snprintf(msg, sizeof(msg),
"Invalid structure definition (native typedef error)");
throwByName(env, EIllegalArgument, msg);
break;
case FFI_OK:
ffi_prep_closure_loc(cb->ffi_closure, &cb->ffi_cif, callback_dispatch, cb,
cb->x_closure);
return cb;
default:
sprintf(msg, "Native callback setup failure: error code %d", status);
snprintf(msg, sizeof(msg),
"Native callback setup failure: error code %d", status);
throwByName(env, EIllegalArgument, msg);
break;
}
failure_cleanup:
free_callback(env, cb);
return NULL;
}
void
@@ -115,23 +119,9 @@ free_callback(JNIEnv* env, callback *cb) {
}
static void
callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
callback* cb = (callback *) user_data;
JavaVM* jvm = cb->vm;
callback_invoke(JNIEnv* env, callback *cb, ffi_cif* cif, void *resp, void **cbargs) {
jobject self;
JNIEnv* env;
int attached;
unsigned int i;
jobjectArray array;
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 to current thread\n");
return;
}
}
self = (*env)->NewLocalRef(env, cb->object);
// Avoid calling back to a GC'd object
if ((*env)->IsSameObject(env, self, NULL)) {
@@ -140,7 +130,10 @@ callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
}
else {
jobject result;
array = (*env)->NewObjectArray(env, cif->nargs, classObject, NULL);
jobjectArray array =
(*env)->NewObjectArray(env, cif->nargs, classObject, NULL);
unsigned int i;
for (i=0;i < cif->nargs;i++) {
jobject arg = new_object(env, cb->param_jtypes[i], cbargs[i]);
(*env)->SetObjectArrayElement(env, array, i, arg);
@@ -154,6 +147,30 @@ callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
extract_value(env, result, resp, cif->rtype->size);
}
}
}
static void
callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
JavaVM* jvm = ((callback *)user_data)->vm;
JNIEnv* env;
int attached;
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 to current thread\n");
return;
}
}
// Give the callback 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");
return;
}
callback_invoke(env, (callback *)user_data, cif, resp, cbargs);
(*env)->PopLocalFrame(env, NULL);
if (!attached) {
(*jvm)->DetachCurrentThread(jvm);
Arquivo executável
+147
Ver Arquivo
@@ -0,0 +1,147 @@
#!/bin/sh
#
# GCC-compatible wrapper for cl.exe
#
MSVC="/c/Program Files (x86)/Microsoft Visual Studio 9.0/vc/bin"
nowarn="/wd4127 /wd4820 /wd4706 /wd4100 /wd4255 /wd4668"
args="/nologo /EHac /W3 /LD $nowarn" # /WX
# FIXME is this equivalent to --static-libgcc? links to msvcrt.lib
# I've forgotten why it was originally added
# /MD causes link problems
#md=/MD
cl="$MSVC/cl"
ml="$MSVC/ml"
output=
while [ $# -gt 0 ]
do
case $1
in
-fexceptions)
shift 1
;;
-fno-omit-frame-pointer)
# TODO: does this have an equivalent?
shift 1
;;
-fno-strict-aliasing)
# TODO: does this have an equivalent?
shift 1
;;
-mno-cygwin)
shift 1
;;
-m32)
cl="$MSVC/cl"
ml="$MSVC/ml"
shift 1
;;
-m64)
cl="$MSVC/x86_amd64/cl"
ml="$MSVC/x86_amd64/ml64"
shift 1
;;
-O*)
args="$args /O1"
shift 1
;;
-g)
# using /RTC1 instead of /GZ
args="$args /Od /D_DEBUG /RTC1 /Zi"
md=/MDd
shift 1
;;
-c)
args="$args /c"
args="$(echo $args | sed 's%/Fe%/Fo%g')"
single="/c"
shift 1
;;
-D*=*)
name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
args="$args -D${name}='$value'"
defines="$defines -D${name}='$value'"
shift 1
;;
-D*)
args="$args $1"
defines="$defines $1"
shift 1
;;
-I)
args="$args /I\"$2\""
includes="$includes /I\"$2\""
shift 2
;;
-I*)
args="$args /I\"$(echo $1|sed -e 's/-I//g')\""
includes="$includes /I\"$(echo $1|sed -e 's/-I//g')\""
shift 1
;;
-W|-Wextra)
# TODO map extra warnings
shift 1
;;
-Wall)
args="$args /Wall"
shift 1
;;
-Werror)
args="$args /WX"
shift 1
;;
-W*)
# TODO map specific warnings
shift 1
;;
-S)
args="$args /FAs"
shift 1
;;
-o)
outdir="$(dirname $2)"
base="$(basename $2|sed 's/\.[^.]*//g')"
if [ -n "$single" ]; then
output="/Fo$2"
else
output="/Fe$2"
fi
if [ -n "$assembly" ]; then
args="$args $output"
else
args="$args $output /Fd$outdir/$base /Fp$outdir/$base /Fa$outdir/$base"
fi
shift 2
;;
*.S)
src="$(echo $1|sed -e 's/.S$/.asm/g' -e 's%\\%/%g')"
echo "$cl /EP $includes $defines $1 > $src"
"$cl" /nologo /EP $includes $defines $1 > $src || exit $?
md=""
cl="$ml"
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
args="/nologo $single $src $output"
assembly="true"
shift 1
;;
*.c)
args="$args $(echo $1|sed -e 's%\\%/%g')"
shift 1
;;
*)
echo "Unsupported argument '$1'"
exit 1
;;
esac
done
args="$md $args"
echo "$cl $args"
eval "\"$cl\" $args"
result=$?
# @#!%@!# ml64 broken output
if [ -n "$assembly" ]; then
mv $src $outdir
mv *.obj $outdir
fi
exit $result
+80 -51
Ver Arquivo
@@ -22,6 +22,9 @@
*/
#if defined(_WIN32)
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _MSC_VER
@@ -31,7 +34,14 @@
#endif
#define LIBNAMETYPE wchar_t*
#define LIBNAME2CSTR(ENV,JSTR) newWideCString(ENV,JSTR)
#define LOAD_LIBRARY(NAME) LoadLibraryW(NAME)
/* See http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx:
* "Note that the standard search strategy and the alternate search strategy
* specified by LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH differ in
* just one way: The standard search begins in the calling application's
* directory, and the alternate search begins in the directory of the
* executable module that LoadLibraryEx is loading."
*/
#define LOAD_LIBRARY(NAME) LoadLibraryExW(NAME, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
#define LOAD_ERROR(BUF,LEN) w32_format_error(BUF, LEN)
#define FREE_LIBRARY(HANDLE) FreeLibrary(HANDLE)
#define FIND_ENTRY(HANDLE, NAME) GetProcAddress(HANDLE, NAME)
@@ -39,8 +49,8 @@
#define SET_LAST_ERROR(CODE) SetLastError(CODE)
static char*
w32_format_error(char* buf, int len) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
0, buf, len, NULL);
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
0, buf, len, NULL);
return buf;
}
#else
@@ -53,7 +63,7 @@ w32_format_error(char* buf, int len) {
#define LIBNAME2CSTR(ENV,JSTR) newCString(ENV,JSTR)
#endif
#define LOAD_LIBRARY(NAME) dlopen(NAME, RTLD_LAZY)
#define LOAD_ERROR(BUF,LEN) (sprintf(BUF, "%s", dlerror()), BUF)
#define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF)
#define FREE_LIBRARY(HANDLE) dlclose(HANDLE)
#define FIND_ENTRY(HANDLE, NAME) dlsym(HANDLE, NAME)
#define GET_LAST_ERROR() errno
@@ -81,9 +91,9 @@ w32_format_error(char* buf, int len) {
#ifdef HAVE_PROTECTION
static int _protect;
#undef PROTECT
#define PROTECT _protect
#endif
#include "protect.h"
#ifdef __cplusplus
extern "C"
@@ -91,9 +101,6 @@ extern "C"
static jboolean preserve_last_error;
#define ON_ERROR() throwByName(env, EError, "Invalid memory access")
#define PSTART() PROTECTED_START()
#define PEND() PROTECTED_END(ON_ERROR())
#define MEMCPY(D,S,L) do { \
PSTART(); memcpy(D,S,L); PEND(); \
} while(0)
@@ -191,6 +198,7 @@ static void *getStructureAddress(JNIEnv *, jobject);
static ffi_type* getStructureType(JNIEnv *, jobject);
static void update_last_error(JNIEnv*, int);
/** Invokes System.err.println (for debugging only). */
static void
println(JNIEnv* env, const char* msg) {
jclass cls = (*env)->FindClass(env, "java/lang/System");
@@ -229,10 +237,11 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
nargs = (*env)->GetArrayLength(env, arr);
if (nargs > MAX_NARGS) {
sprintf(msg, "Too many arguments (max %ld)", MAX_NARGS);
snprintf(msg, sizeof(msg), "Too many arguments (max %ld)", MAX_NARGS);
throwByName(env, EUnsupportedOperation, msg);
return;
}
c_args = (jvalue*)alloca(nargs * sizeof(jvalue));
array_elements = (struct _array_elements*)
alloca(nargs * sizeof(struct _array_elements));
@@ -277,7 +286,7 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
ffi_values[i] = &c_args[i].i;
}
else {
sprintf(msg, "Unsupported wchar_t size (%d)", (int)sizeof(wchar_t));
snprintf(msg, sizeof(msg), "Unsupported wchar_t size (%d)", (int)sizeof(wchar_t));
throwByName(env, EUnsupportedOperation, msg);
goto cleanup;
}
@@ -312,7 +321,8 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
ffi_types[i] = getStructureType(env, arg);
ffi_values[i] = c_args[i].l;
if (!ffi_types[i]) {
sprintf(msg, "Structure type info not initialized at argument %d", i);
snprintf(msg, sizeof(msg),
"Structure type info not initialized at argument %d", i);
throwByName(env, EIllegalState, msg);
goto cleanup;
}
@@ -322,22 +332,21 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
ffi_types[i] = &ffi_type_pointer;
ffi_values[i] = &c_args[i].l;
if (c_args[i].l == NULL) {
c_args[i].l =
getBufferArray(env, arg, &array_elements[array_count].array,
&array_elements[array_count].type,
&array_elements[array_count].elems);
if (c_args[i].l == NULL) {
throwByName(env, EIllegalArgument,
"Buffer arguments must be direct or have a primitive backing array");
goto cleanup;
}
++array_count;
c_args[i].l =
getBufferArray(env, arg, &array_elements[array_count].array,
&array_elements[array_count].type,
&array_elements[array_count].elems);
if (c_args[i].l == NULL) {
throwByName(env, EIllegalArgument,
"Buffer arguments must be direct or have a primitive backing array");
goto cleanup;
}
++array_count;
}
}
else if ((array_pt = getArrayComponentType(env, arg)) != 0
&& array_pt != 'L') {
void *ptr = NULL;
switch(array_pt) {
case 'Z': ptr = (*env)->GetBooleanArrayElements(env, arg, NULL); break;
case 'B': ptr = (*env)->GetByteArrayElements(env, arg, NULL); break;
@@ -361,7 +370,7 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
array_elements[array_count++].elems = ptr;
}
else {
sprintf(msg, "Unsupported type at parameter %d", i);
snprintf(msg, sizeof(msg), "Unsupported type at parameter %d", i);
throwByName(env,EIllegalArgument, msg);
goto cleanup;
}
@@ -371,24 +380,33 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
case CALLCONV_C:
abi = FFI_DEFAULT_ABI;
break;
#if defined(_WIN32)
#ifdef _WIN32
case CALLCONV_STDCALL:
#ifdef _WIN64
// Ignore requests for stdcall on win64
abi = FFI_DEFAULT_ABI;
#else
abi = FFI_STDCALL;
#endif
break;
#endif // _WIN32
default:
sprintf(msg, "Unrecognized calling convention: %d", (int)callconv);
snprintf(msg, sizeof(msg),
"Unrecognized calling convention: %d", (int)callconv);
throwByName(env, EIllegalArgument, msg);
goto cleanup;
}
status = ffi_prep_cif(&cif, abi, nargs, ffi_return_type, ffi_types);
switch(status) {
case FFI_BAD_ABI:
sprintf(msg, "Invalid calling convention: %d", (int)callconv);
snprintf(msg, sizeof(msg),
"Invalid calling convention: %d", (int)callconv);
throwByName(env, EIllegalArgument, msg);
break;
case FFI_BAD_TYPEDEF:
sprintf(msg, "Invalid structure definition (native typedef error)");
snprintf(msg, sizeof(msg),
"Invalid structure definition (native typedef error)");
throwByName(env, EIllegalArgument, msg);
break;
case FFI_OK: {
@@ -401,7 +419,8 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
break;
}
default:
sprintf(msg, "Native call setup failure: error code %d", status);
snprintf(msg, sizeof(msg),
"Native call setup failure: error code %d", status);
throwByName(env, EIllegalArgument, msg);
break;
}
@@ -997,7 +1016,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Pointer__1read__J_3SII
JNIEXPORT jbyte JNICALL Java_com_sun_jna_Pointer__1getByte
(JNIEnv *env, jclass cls, jlong addr)
{
jbyte res;
jbyte res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1010,7 +1029,7 @@ JNIEXPORT jbyte JNICALL Java_com_sun_jna_Pointer__1getByte
JNIEXPORT jchar JNICALL Java_com_sun_jna_Pointer__1getChar
(JNIEnv *env, jclass cls, jlong addr)
{
wchar_t res;
wchar_t res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return (jchar)res;
}
@@ -1023,7 +1042,7 @@ JNIEXPORT jchar JNICALL Java_com_sun_jna_Pointer__1getChar
JNIEXPORT jobject JNICALL Java_com_sun_jna_Pointer__1getPointer
(JNIEnv *env, jclass cls, jlong addr)
{
void *ptr;
void *ptr = NULL;
MEMCPY(&ptr, L2A(addr), sizeof(ptr));
return newJavaPointer(env, ptr);
}
@@ -1047,7 +1066,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_jna_Pointer__1getDirectByteBuffer
JNIEXPORT jdouble JNICALL Java_com_sun_jna_Pointer__1getDouble
(JNIEnv *env, jclass cls, jlong addr)
{
jdouble res;
jdouble res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1060,7 +1079,7 @@ JNIEXPORT jdouble JNICALL Java_com_sun_jna_Pointer__1getDouble
JNIEXPORT jfloat JNICALL Java_com_sun_jna_Pointer__1getFloat
(JNIEnv *env, jclass cls, jlong addr)
{
jfloat res;
jfloat res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1073,7 +1092,7 @@ JNIEXPORT jfloat JNICALL Java_com_sun_jna_Pointer__1getFloat
JNIEXPORT jint JNICALL Java_com_sun_jna_Pointer__1getInt
(JNIEnv *env, jclass cls, jlong addr)
{
jint res;
jint res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1086,7 +1105,7 @@ JNIEXPORT jint JNICALL Java_com_sun_jna_Pointer__1getInt
JNIEXPORT jlong JNICALL Java_com_sun_jna_Pointer__1getLong
(JNIEnv *env, jclass cls, jlong addr)
{
jlong res;
jlong res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1099,7 +1118,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_jna_Pointer__1getLong
JNIEXPORT jshort JNICALL Java_com_sun_jna_Pointer__1getShort
(JNIEnv *env, jclass cls, jlong addr)
{
jshort res;
jshort res = 0;
MEMCPY(&res, L2A(addr), sizeof(res));
return res;
}
@@ -1379,7 +1398,7 @@ newJavaString(JNIEnv *env, const char *ptr, jboolean wide)
if (wide) {
// TODO: proper conversion from native wchar_t to jchar
int len = wcslen((const wchar_t*)ptr);
int len = (int)wcslen((const wchar_t*)ptr);
if (sizeof(jchar) != sizeof(wchar_t)) {
jchar* buf = (jchar*)alloca(len * sizeof(jchar));
int i;
@@ -1394,7 +1413,7 @@ newJavaString(JNIEnv *env, const char *ptr, jboolean wide)
}
else {
jbyteArray bytes = 0;
int len = strlen(ptr);
int len = (int)strlen(ptr);
bytes = (*env)->NewByteArray(env, len);
if (bytes != 0) {
@@ -1534,6 +1553,7 @@ do { jboolean cpy; \
*elemp = ptr;
ptr = (char *)ptr + offset;
}
return ptr;
}
@@ -1652,7 +1672,7 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
return;
}
for (i=0;i < sizeof(fields)/sizeof(fields[0]);i++) {
sprintf(field, "ffi_type_%s", fields[i]);
snprintf(field, sizeof(field), "ffi_type_%s", fields[i]);
fid = (*env)->GetStaticFieldID(env, cls, field, "Lcom/sun/jna/Pointer;");
if (!fid) {
throwByName(env, EUnsatisfiedLink, field);
@@ -1667,13 +1687,13 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
#define JAWT_HEADLESS_HACK
#ifdef _WIN32
#define JAWT_NAME "jawt.dll"
#define METHOD_NAME (sizeof(void*)==4?"_JAWT_GetAWT@8":"_JAWT_GetAWT@16")
#define METHOD_NAME (sizeof(void*)==4?"_JAWT_GetAWT@8":"JAWT_GetAWT")
#else
#define JAWT_NAME "libjawt.so"
#define METHOD_NAME "JAWT_GetAWT"
#endif
static void* jawt_handle = NULL;
static jboolean JNICALL (*pJAWT_GetAWT)(JNIEnv*,JAWT*);
static jboolean (JNICALL *pJAWT_GetAWT)(JNIEnv*,JAWT*);
#define JAWT_GetAWT (*pJAWT_GetAWT)
#endif
@@ -1714,16 +1734,20 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
if (java_home != NULL) {
if ((prop = newWideCString(env, java_home)) != NULL) {
const wchar_t* suffix = L"/bin/jawt.dll";
path = (wchar_t*)alloca((wcslen(prop) + wcslen(suffix) + 1)
* sizeof(wchar_t));
size_t len = wcslen(prop) + wcslen(suffix) + 1;
path = (wchar_t*)alloca(len * sizeof(wchar_t));
#ifdef _MSC_VER
swprintf(path, len, L"%s%s", prop, suffix);
#else
swprintf(path, L"%s%s", prop, suffix);
#endif
free(prop);
}
}
}
}
#undef LOAD_LIBRARY
#define LOAD_LIBRARY(X) LoadLibraryW(path)
#undef JAWT_NAME
#define JAWT_NAME path
#endif
if ((jawt_handle = LOAD_LIBRARY(JAWT_NAME)) == NULL) {
char msg[1024];
@@ -1732,7 +1756,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
}
if ((pJAWT_GetAWT = (void*)FIND_ENTRY(jawt_handle, METHOD_NAME)) == NULL) {
char msg[1024], buf[1024];
sprintf(msg, "Error looking up %s: %s",
snprintf(msg, sizeof(msg), "Error looking up %s: %s",
METHOD_NAME, LOAD_ERROR(buf, sizeof(buf)));
throwByName(env, EUnsatisfiedLink, msg);
return -1;
@@ -1768,7 +1792,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
// FIXME this kills the VM if the window is not realized;
// if not, wdsi might be a bogus, non-null value
// TODO: fix JVM (right) or ensure window is realized (done in Java)
handle = (jint)wdsi->hwnd;
handle = A2L(wdsi->hwnd);
if (!handle) {
throwByName(env, EIllegalState, "Can't get HWND");
}
@@ -1828,14 +1852,19 @@ Java_com_sun_jna_Native_setProtected(JNIEnv *env, jclass classp, jboolean protec
#endif
}
JNIEXPORT jboolean JNICALL
Java_com_sun_jna_Native_isProtected(JNIEnv *env, jclass classp) {
#ifdef HAVE_PROTECTION
jboolean
is_protected() {
#ifdef HAVE_PROTECTION
if (_protect) return JNI_TRUE;
#endif
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_com_sun_jna_Native_isProtected(JNIEnv *env, jclass classp) {
return is_protected();
}
JNIEXPORT void JNICALL
Java_com_sun_jna_Native_setPreserveLastError(JNIEnv *env, jclass classp, jboolean preserve) {
preserve_last_error = preserve;
@@ -2082,7 +2111,7 @@ get_ffi_rtype(JNIEnv* env, jclass cls, char jtype) {
return get_ffi_type(env, cls, jtype);
}
}
#ifdef __cplusplus
}
#endif
+18 -1
Ver Arquivo
@@ -23,7 +23,7 @@ extern "C" {
/* These are the calling conventions an invocation can handle. */
typedef enum _callconv {
CALLCONV_C = com_sun_jna_Function_C_CONVENTION,
#if defined(_WIN32)
#ifdef _WIN32
CALLCONV_STDCALL = com_sun_jna_Function_ALT_CONVENTION,
#endif
} callconv_t;
@@ -47,13 +47,19 @@ typedef struct _callback {
typedef long word_t;
#if defined(SOLARIS2) || defined(__GNUC__)
#if defined(_WIN64)
#define L2A(X) ((void *)(long long)(X))
#define A2L(X) ((jlong)(long long)(X))
#else
#define L2A(X) ((void *)(unsigned long)(X))
#define A2L(X) ((jlong)(unsigned long)(X))
#endif
#endif
#if defined(_MSC_VER)
#define L2A(X) ((void *)(X))
#define A2L(X) ((jlong)(X))
#define snprintf sprintf_s
#endif
/* Convenience macros */
@@ -96,6 +102,17 @@ extern callback* create_callback(JNIEnv*, jobject, jobject,
extern void free_callback(JNIEnv*, callback*);
extern void extract_value(JNIEnv*, jobject, void*, size_t size);
extern jobject new_object(JNIEnv*, char, void*);
extern jboolean is_protected();
/* 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 __cplusplus
}
#endif
Arquivo executável
+56
Ver Arquivo
@@ -0,0 +1,56 @@
#!/bin/sh
#
# ld-compatible wrapper for link.exe
#
#args="/pdbtype:sept"
MSVC="/c/Program Files (x86)/Microsoft Visual Studio 9.0/vc/bin"
args="/nologo /opt:REF /incremental:no /subsystem:console /nodefaultlib:msvcrtd"
link="$MSVC/link"
while [ $# -gt 0 ]
do
case $1
in
-m32)
link="$MSVC/link"
args="$args /machine:X86"
shift 1
;;
-m64)
link="$MSVC/x86_amd64/link"
args="$args /machine:X64"
shift 1
;;
-g)
args="$args /debug"
shift 1
;;
-o)
dir="$(dirname $2)"
base="$(basename $2|sed 's/\.[^.]*//g')"
args="$args /out:\"$2\" /pdb:$dir/$base.pdb /implib:$dir/$base.lib"
shift 2
;;
-shared)
args="$args /DLL"
shift 1
;;
-static-libgcc)
shift 1
;;
*.dll)
args="$args $(echo $1|sed -e 's/.dll/.lib/g')"
shift 1
;;
*.o|*.lib|*.a)
args="$args $(echo $1|sed -e 's%\\%/%g')"
shift 1
;;
*)
echo "Unsupported argument '$1'"
exit 1
;;
esac
done
echo "\"$link\" $args"
eval "\"$link\" $args"
+5 -1
Ver Arquivo
@@ -26,7 +26,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/win64.S \
src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
@@ -93,6 +94,9 @@ endif
if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif
if X86_WIN64
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
+59 -46
Ver Arquivo
@@ -40,25 +40,26 @@ target_triplet = @target@
@MIPS_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
@X86_TRUE@am__append_2 = src/x86/ffi.c src/x86/sysv.S
@X86_WIN32_TRUE@am__append_3 = src/x86/ffi.c src/x86/win32.S
@X86_DARWIN_TRUE@am__append_4 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
@SPARC_TRUE@am__append_5 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
@ALPHA_TRUE@am__append_6 = src/alpha/ffi.c src/alpha/osf.S
@IA64_TRUE@am__append_7 = src/ia64/ffi.c src/ia64/unix.S
@M32R_TRUE@am__append_8 = src/m32r/sysv.S src/m32r/ffi.c
@M68K_TRUE@am__append_9 = src/m68k/ffi.c src/m68k/sysv.S
@POWERPC_TRUE@am__append_10 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
@POWERPC_AIX_TRUE@am__append_11 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
@POWERPC_DARWIN_TRUE@am__append_12 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
@POWERPC_FREEBSD_TRUE@am__append_13 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
@ARM_TRUE@am__append_14 = src/arm/sysv.S src/arm/ffi.c
@LIBFFI_CRIS_TRUE@am__append_15 = src/cris/sysv.S src/cris/ffi.c
@FRV_TRUE@am__append_16 = src/frv/eabi.S src/frv/ffi.c
@S390_TRUE@am__append_17 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_18 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_19 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_20 = src/sh64/sysv.S src/sh64/ffi.c
@PA_LINUX_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c
@PA_HPUX_TRUE@am__append_22 = src/pa/hpux32.S src/pa/ffi.c
@X86_WIN64_TRUE@am__append_4 = src/x86/ffi.c src/x86/win64.S
@X86_DARWIN_TRUE@am__append_5 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
@SPARC_TRUE@am__append_6 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
@ALPHA_TRUE@am__append_7 = src/alpha/ffi.c src/alpha/osf.S
@IA64_TRUE@am__append_8 = src/ia64/ffi.c src/ia64/unix.S
@M32R_TRUE@am__append_9 = src/m32r/sysv.S src/m32r/ffi.c
@M68K_TRUE@am__append_10 = src/m68k/ffi.c src/m68k/sysv.S
@POWERPC_TRUE@am__append_11 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
@POWERPC_AIX_TRUE@am__append_12 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
@POWERPC_DARWIN_TRUE@am__append_13 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
@POWERPC_FREEBSD_TRUE@am__append_14 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
@ARM_TRUE@am__append_15 = src/arm/sysv.S src/arm/ffi.c
@LIBFFI_CRIS_TRUE@am__append_16 = src/cris/sysv.S src/cris/ffi.c
@FRV_TRUE@am__append_17 = src/frv/eabi.S src/frv/ffi.c
@S390_TRUE@am__append_18 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_19 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_20 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_21 = src/sh64/sysv.S src/sh64/ffi.c
@PA_LINUX_TRUE@am__append_22 = src/pa/linux.S src/pa/ffi.c
@PA_HPUX_TRUE@am__append_23 = src/pa/hpux32.S src/pa/ffi.c
DIST_COMMON = README $(am__configure_deps) $(srcdir)/../compile \
$(srcdir)/../config.guess $(srcdir)/../config.sub \
$(srcdir)/../depcomp $(srcdir)/../install-sh \
@@ -98,37 +99,38 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@MIPS_TRUE@ src/mips/n32.lo
@X86_TRUE@am__objects_2 = src/x86/ffi.lo src/x86/sysv.lo
@X86_WIN32_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/win32.lo
@X86_DARWIN_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/darwin.lo \
@X86_WIN64_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/win64.lo
@X86_DARWIN_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/darwin.lo \
@X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo
@SPARC_TRUE@am__objects_5 = src/sparc/ffi.lo src/sparc/v8.lo \
@SPARC_TRUE@am__objects_6 = src/sparc/ffi.lo src/sparc/v8.lo \
@SPARC_TRUE@ src/sparc/v9.lo
@ALPHA_TRUE@am__objects_6 = src/alpha/ffi.lo src/alpha/osf.lo
@IA64_TRUE@am__objects_7 = src/ia64/ffi.lo src/ia64/unix.lo
@M32R_TRUE@am__objects_8 = src/m32r/sysv.lo src/m32r/ffi.lo
@M68K_TRUE@am__objects_9 = src/m68k/ffi.lo src/m68k/sysv.lo
@POWERPC_TRUE@am__objects_10 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
@ALPHA_TRUE@am__objects_7 = src/alpha/ffi.lo src/alpha/osf.lo
@IA64_TRUE@am__objects_8 = src/ia64/ffi.lo src/ia64/unix.lo
@M32R_TRUE@am__objects_9 = src/m32r/sysv.lo src/m32r/ffi.lo
@M68K_TRUE@am__objects_10 = src/m68k/ffi.lo src/m68k/sysv.lo
@POWERPC_TRUE@am__objects_11 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
@POWERPC_TRUE@ src/powerpc/ppc_closure.lo \
@POWERPC_TRUE@ src/powerpc/linux64.lo \
@POWERPC_TRUE@ src/powerpc/linux64_closure.lo
@POWERPC_AIX_TRUE@am__objects_11 = src/powerpc/ffi_darwin.lo \
@POWERPC_AIX_TRUE@am__objects_12 = src/powerpc/ffi_darwin.lo \
@POWERPC_AIX_TRUE@ src/powerpc/aix.lo \
@POWERPC_AIX_TRUE@ src/powerpc/aix_closure.lo
@POWERPC_DARWIN_TRUE@am__objects_12 = src/powerpc/ffi_darwin.lo \
@POWERPC_DARWIN_TRUE@am__objects_13 = src/powerpc/ffi_darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin_closure.lo
@POWERPC_FREEBSD_TRUE@am__objects_13 = src/powerpc/ffi.lo \
@POWERPC_FREEBSD_TRUE@am__objects_14 = src/powerpc/ffi.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
@ARM_TRUE@am__objects_14 = src/arm/sysv.lo src/arm/ffi.lo
@LIBFFI_CRIS_TRUE@am__objects_15 = src/cris/sysv.lo src/cris/ffi.lo
@FRV_TRUE@am__objects_16 = src/frv/eabi.lo src/frv/ffi.lo
@S390_TRUE@am__objects_17 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_18 = src/x86/ffi64.lo src/x86/unix64.lo \
@ARM_TRUE@am__objects_15 = src/arm/sysv.lo src/arm/ffi.lo
@LIBFFI_CRIS_TRUE@am__objects_16 = src/cris/sysv.lo src/cris/ffi.lo
@FRV_TRUE@am__objects_17 = src/frv/eabi.lo src/frv/ffi.lo
@S390_TRUE@am__objects_18 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_19 = src/x86/ffi64.lo src/x86/unix64.lo \
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
@SH_TRUE@am__objects_19 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_20 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_LINUX_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo
@PA_HPUX_TRUE@am__objects_22 = src/pa/hpux32.lo src/pa/ffi.lo
@SH_TRUE@am__objects_20 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_21 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_LINUX_TRUE@am__objects_22 = src/pa/linux.lo src/pa/ffi.lo
@PA_HPUX_TRUE@am__objects_23 = src/pa/hpux32.lo src/pa/ffi.lo
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
@@ -136,22 +138,22 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21) $(am__objects_22)
$(am__objects_21) $(am__objects_22) $(am__objects_23)
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
$(nodist_libffi_la_OBJECTS)
libffi_convenience_la_LIBADD =
am__objects_23 = src/debug.lo src/prep_cif.lo src/types.lo \
am__objects_24 = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo src/closures.lo
am_libffi_convenience_la_OBJECTS = $(am__objects_23)
am__objects_24 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
am_libffi_convenience_la_OBJECTS = $(am__objects_24)
am__objects_25 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13) $(am__objects_14) $(am__objects_15) \
$(am__objects_16) $(am__objects_17) $(am__objects_18) \
$(am__objects_19) $(am__objects_20) $(am__objects_21) \
$(am__objects_22)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_24)
$(am__objects_22) $(am__objects_23)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_25)
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
$(nodist_libffi_convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
@@ -307,6 +309,8 @@ X86_FALSE = @X86_FALSE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
X86_WIN64_FALSE = @X86_WIN64_FALSE@
X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -379,7 +383,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/win64.S \
src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
@@ -435,7 +440,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_12) $(am__append_13) $(am__append_14) \
$(am__append_15) $(am__append_16) $(am__append_17) \
$(am__append_18) $(am__append_19) $(am__append_20) \
$(am__append_21) $(am__append_22)
$(am__append_21) $(am__append_22) $(am__append_23)
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
@@ -569,6 +574,8 @@ src/x86/sysv.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/win32.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/win64.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/darwin.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/ffi64.lo: src/x86/$(am__dirstamp) \
@@ -836,6 +843,8 @@ mostlyclean-compile:
-rm -f src/x86/unix64.lo
-rm -f src/x86/win32.$(OBJEXT)
-rm -f src/x86/win32.lo
-rm -f src/x86/win64.$(OBJEXT)
-rm -f src/x86/win64.lo
distclean-compile:
-rm -f *.tab.c
@@ -863,6 +872,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/unix64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/win32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/win64.Plo@am__quote@
.S.o:
$(CCASCOMPILE) -c $<
+21 -1
Ver Arquivo
@@ -459,7 +459,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CPP CPPFLAGS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_TRUE MIPS_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE X86_DARWIN_TRUE X86_DARWIN_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE POWERPC_FREEBSD_TRUE POWERPC_FREEBSD_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_LINUX_TRUE PA_LINUX_FALSE PA_HPUX_TRUE PA_HPUX_FALSE PA64_HPUX_TRUE PA64_HPUX_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CPP CPPFLAGS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_TRUE MIPS_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE X86_WIN64_TRUE X86_WIN64_FALSE X86_DARWIN_TRUE X86_DARWIN_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE POWERPC_FREEBSD_TRUE POWERPC_FREEBSD_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_LINUX_TRUE PA_LINUX_FALSE PA_HPUX_TRUE PA_HPUX_FALSE PA64_HPUX_TRUE PA64_HPUX_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -10370,6 +10370,7 @@ case "$host" in
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
@@ -10426,6 +10427,16 @@ fi
if test x$TARGET = xX86_WIN64; then
X86_WIN64_TRUE=
X86_WIN64_FALSE='#'
else
X86_WIN64_TRUE='#'
X86_WIN64_FALSE=
fi
if test x$TARGET = xX86_DARWIN; then
X86_DARWIN_TRUE=
X86_DARWIN_FALSE='#'
@@ -12826,6 +12837,13 @@ echo "$as_me: error: conditional \"X86_WIN32\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${X86_WIN64_TRUE}" && test -z "${X86_WIN64_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"X86_WIN64\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"X86_WIN64\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"X86_DARWIN\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -13838,6 +13856,8 @@ s,@X86_TRUE@,$X86_TRUE,;t t
s,@X86_FALSE@,$X86_FALSE,;t t
s,@X86_WIN32_TRUE@,$X86_WIN32_TRUE,;t t
s,@X86_WIN32_FALSE@,$X86_WIN32_FALSE,;t t
s,@X86_WIN64_TRUE@,$X86_WIN64_TRUE,;t t
s,@X86_WIN64_FALSE@,$X86_WIN64_FALSE,;t t
s,@X86_DARWIN_TRUE@,$X86_DARWIN_TRUE,;t t
s,@X86_DARWIN_FALSE@,$X86_DARWIN_FALSE,;t t
s,@ALPHA_TRUE@,$ALPHA_TRUE,;t t
+2
Ver Arquivo
@@ -139,6 +139,7 @@ case "$host" in
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
@@ -155,6 +156,7 @@ AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
AM_CONDITIONAL(X86, test x$TARGET = xX86)
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
+2
Ver Arquivo
@@ -175,6 +175,8 @@ X86_FALSE = @X86_FALSE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
X86_WIN64_FALSE = @X86_WIN64_FALSE@
X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+4
Ver Arquivo
@@ -64,6 +64,10 @@ extern "C" {
#ifndef LIBFFI_ASM
#ifdef _MSC_VER
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
+15
Ver Arquivo
@@ -29,7 +29,11 @@ extern "C" {
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
# ifdef _MSC_VER
# define alloca _alloca
# else
char *alloca ();
# endif
# endif
# endif
# endif
@@ -77,6 +81,16 @@ typedef struct
} extended_cif;
/* Terse sized type definitions. */
#ifdef _MSC_VER
typedef unsigned char UINT8;
typedef signed char SINT8;
typedef unsigned short UINT16;
typedef signed short SINT16;
typedef unsigned int UINT32;
typedef signed int SINT32;
typedef unsigned __int64 UINT64;
typedef signed __int64 SINT64;
#else
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
@@ -85,6 +99,7 @@ typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
#endif
typedef float FLOAT32;
+25
Ver Arquivo
@@ -41,6 +41,13 @@
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
# if defined(X86_WIN32) || defined(X86_WIN64)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
@@ -59,7 +66,9 @@
#define USE_LOCKS 1
#define USE_DL_PREFIX 1
#ifdef __GNUC__
#define USE_BUILTIN_FFS 1
#endif
/* We need to use mmap, not sbrk. */
#define HAVE_MORECORE 0
@@ -89,10 +98,15 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#if !defined(X86_WIN32) && !defined(X86_WIN64)
#ifdef HAVE_MNTENT
#include <mntent.h>
#endif /* HAVE_MNTENT */
#include <sys/param.h>
#include <pthread.h>
@@ -149,6 +163,7 @@ selinux_enabled_check (void)
#define is_selinux_enabled() 0
#endif
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */
static void *dlmalloc(size_t);
@@ -167,9 +182,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
#if !defined(X86_WIN32) && !defined(X86_WIN64)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
#define mmap dlmmap
#define munmap dlmunmap
@@ -179,6 +196,8 @@ static int dlmunmap(void *, size_t);
#undef mmap
#undef munmap
#if !defined(X86_WIN32) && !defined(X86_WIN64)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -231,6 +250,7 @@ open_temp_exec_file_env (const char *envvar)
return open_temp_exec_file_dir (value);
}
#ifdef HAVE_MNTENT
/* Open a temporary file in an executable and writable mount point
listed in the mounts file. Subsequent calls with the same mounts
keep searching for mount points in the same file. Providing NULL
@@ -277,6 +297,7 @@ open_temp_exec_file_mnt (const char *mounts)
return fd;
}
}
#endif /* HAVE_MNTENT */
/* Instructions to look for a location to hold a temporary file that
can be mapped in for execution. */
@@ -291,8 +312,10 @@ static struct
{ open_temp_exec_file_dir, "/var/tmp", 0 },
{ open_temp_exec_file_dir, "/dev/shm", 0 },
{ open_temp_exec_file_env, "HOME", 0 },
#ifdef HAVE_MNTENT
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
#endif /* HAVE_MNTENT */
};
/* Current index into open_temp_exec_file_opts. */
@@ -488,6 +511,8 @@ segment_holding_code (mstate m, char* addr)
}
#endif
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
+4 -4
Ver Arquivo
@@ -1140,9 +1140,9 @@ int mspace_mallopt(int, int);
/*------------------------------ internal #includes ---------------------- */
#ifdef WIN32
#ifdef _MSC_VER
#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
#endif /* WIN32 */
#endif /* _MSC_VER */
#include <stdio.h> /* for printing in malloc_stats */
@@ -1315,14 +1315,14 @@ static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
/* Win32 MMAP via VirtualAlloc */
static void* win32mmap(size_t size) {
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
static void* win32direct_mmap(size_t size) {
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
PAGE_READWRITE);
PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
+172 -28
Ver Arquivo
@@ -3,7 +3,7 @@
Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle
Copyright (c) 2007 Timothy Wall
Copyright (c) 2007,2008 Timothy Wall
x86 Foreign Function Interface
@@ -27,7 +27,7 @@
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef __x86_64__
#if !defined(__x86_64__) || defined(_WIN64)
#include <ffi.h>
#include <ffi_common.h>
@@ -46,10 +46,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = stack;
if (ecif->cif->flags == FFI_TYPE_STRUCT)
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
{
*(void **) argp = ecif->rvalue;
argp += 4;
argp += sizeof(void*);
}
p_argv = ecif->avalue;
@@ -61,42 +61,48 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
size_t z;
/* Align if necessary */
if ((sizeof(int) - 1) & (unsigned) argp)
argp = (char *) ALIGN(argp, sizeof(int));
if ((sizeof(void*) - 1) & (size_t) argp)
argp = (char *) ALIGN(argp, sizeof(void*));
z = (*p_arg)->size;
if (z < sizeof(int))
if (z < sizeof(ffi_arg))
{
z = sizeof(int);
z = sizeof(ffi_arg);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
*(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
*(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
*(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
*(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
break;
case FFI_TYPE_SINT32:
*(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
*(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
break;
case FFI_TYPE_UINT32:
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
*(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
break;
case FFI_TYPE_STRUCT:
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
*(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
break;
#ifdef X86_WIN64
case FFI_TYPE_FLOAT:
memcpy(argp, *p_argv, z);
break;
#endif
default:
FFI_ASSERT(0);
@@ -104,8 +110,25 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
}
else
{
#ifdef X86_WIN64
// Structs larger than 8 bytes are passed by reference
// Incoming data is always a pointer
if ((*p_arg)->type == FFI_TYPE_STRUCT)
{
if (z == FFI_SIZEOF_ARG)
{
*(ffi_arg *)argp = *(ffi_arg *)(* p_argv);
}
else
{
*(void **)argp = *p_argv;
}
}
else
#endif
memcpy(argp, *p_argv, z);
}
p_argv++;
argp += z;
}
@@ -131,11 +154,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_UINT64:
#ifdef X86_WIN64
case FFI_TYPE_POINTER:
#endif
cif->flags = FFI_TYPE_SINT64;
break;
@@ -173,6 +201,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
#ifdef X86_WIN64
// ensure at least 40 bytes storage, one optional return address
// and four registers
cif->bytes = cif->bytes < 40 ? 40 : cif->bytes;
#endif
return FFI_OK;
}
@@ -184,6 +218,11 @@ extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)());
#endif /* X86_WIN32 */
#ifdef X86_WIN64
extern int
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)());
#endif
void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
{
@@ -196,7 +235,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
/* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->flags == FFI_TYPE_STRUCT))
(cif->rtype->type == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
@@ -206,6 +245,27 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
switch (cif->abi)
{
#ifdef X86_WIN64
// TODO: check small struct return, args
case FFI_WIN64:
{
// Make copies of all struct arguments
// NOTE: not sure if responsibility should be here or in caller
unsigned int i;
for (i=0; i < cif->nargs;i++) {
size_t size = cif->arg_types[i]->size;
if (cif->arg_types[i]->type == FFI_TYPE_STRUCT
&& size > sizeof(void *)) {
void *local = alloca(size);
memcpy(local, avalue[i], size);
avalue[i] = local;
}
}
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
}
break;
#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn);
@@ -216,6 +276,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
ecif.rvalue, fn);
break;
#endif /* X86_WIN32 */
#endif
default:
FFI_ASSERT(0);
break;
@@ -236,10 +297,43 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
#ifdef X86_WIN32
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
#endif /* X86_WIN32 */
#ifdef X86_WIN64
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
#endif
/* This function is jumped to by the trampoline */
#ifdef X86_WIN64
void * FFI_HIDDEN
ffi_closure_win64_inner (ffi_closure *closure, void *args) {
ffi_cif *cif;
void **arg_area;
void *result;
void *resp = &result;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will change RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
/* The result is returned in rax. This does the right thing for
result types except for floats; we have to 'mov xmm0, rax' in the
caller to correct this.
*/
return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
}
#else
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
@@ -256,16 +350,19 @@ ffi_closure_SYSV_inner (closure, respp, args)
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will re-set RESP to point to the
* a structure, it will change RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
(closure->fun) (cif, *respp, arg_area, closure->user_data);
return cif->flags;
}
#endif /* !X86_WIN64 */
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
ffi_cif *cif)
@@ -277,10 +374,17 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
argp = stack;
if ( cif->flags == FFI_TYPE_STRUCT ) {
#ifdef X86_WIN64
if (cif->rtype->size > sizeof(void *)) {
*rvalue = *(void **) argp;
argp += 4;
argp += sizeof(void *);
}
#else
if (cif->rtype->type == FFI_TYPE_STRUCT) {
*rvalue = *(void **) argp;
argp += sizeof(void *);
}
#endif
p_argv = avalue;
@@ -289,15 +393,25 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
size_t z;
/* Align if necessary */
if ((sizeof(int) - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, sizeof(int));
if ((sizeof(void*) - 1) & (size_t) argp) {
argp = (char *) ALIGN(argp, sizeof(void*));
}
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
#ifdef X86_WIN64
if ((*p_arg)->size > sizeof(void *))
{
z = sizeof(void *);
*p_argv = *(void **)argp;
}
else
#endif
{
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
}
p_argv++;
argp += z;
@@ -306,6 +420,24 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
return;
}
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
void* __fun = (void*)(FUN); \
void* __ctx = (void*)(CTX); \
*(unsigned char*) &__tramp[0] = 0x41; \
*(unsigned char*) &__tramp[1] = 0xbb; \
*(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
*(unsigned char*) &__tramp[6] = 0x48; \
*(unsigned char*) &__tramp[7] = 0xb8; \
*(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
*(unsigned char *) &__tramp[16] = 0x49; \
*(unsigned char *) &__tramp[17] = 0xba; \
*(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
*(unsigned char *) &__tramp[26] = 0x41; \
*(unsigned char *) &__tramp[27] = 0xff; \
*(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
}
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
@@ -342,6 +474,17 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *user_data,
void *codeloc)
{
#ifdef X86_WIN64
#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
if (cif->abi == FFI_WIN64)
{
int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
&ffi_closure_win64,
codeloc, mask);
}
#else
if (cif->abi == FFI_SYSV)
{
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
@@ -355,7 +498,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
&ffi_closure_STDCALL,
codeloc, cif->bytes);
}
#endif
#endif /* X86_WIN32 */
#endif /* !X86_WIN64 */
else
{
return FFI_BAD_ABI;
@@ -467,4 +611,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
#endif
#endif /* __x86_64__ */
#endif /* !__x86_64__ || X86_WIN64 */
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
ffi64.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
x86-64 Foreign Function Interface
+28
Ver Arquivo
@@ -33,11 +33,26 @@
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
#define USE_BUILTIN_FFS 0 // until mingw-64 gets it
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef unsigned __int64 ffi_arg;
typedef __int64 ffi_sarg;
#else
typedef unsigned long long ffi_arg;
typedef long long ffi_sarg;
#endif
#else
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
#endif
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
@@ -50,6 +65,10 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_SYSV,
#endif
#ifdef X86_WIN64
FFI_WIN64,
FFI_DEFAULT_ABI = FFI_WIN64,
#else
/* ---- Intel x86 and AMD x86-64 - */
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
FFI_SYSV,
@@ -60,6 +79,7 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_UNIX64,
#endif
#endif
#endif /* X86_WIN64 */
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
@@ -76,10 +96,18 @@ typedef enum ffi_abi {
#ifdef X86_WIN32
#define FFI_TRAMPOLINE_SIZE 13
#else
#ifdef X86_WIN64
#define FFI_TRAMPOLINE_SIZE 29
#define FFI_NATIVE_RAW_API 0
#define FFI_NO_RAW_API 1
#else
#define FFI_TRAMPOLINE_SIZE 10
#endif
#endif
#ifndef X86_WIN64
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
#endif
#endif
-2
Ver Arquivo
@@ -33,8 +33,6 @@
.text
.globl ffi_prep_args
# This assumes we are using gas.
.balign 16
.globl _ffi_call_SYSV
+311
Ver Arquivo
@@ -0,0 +1,311 @@
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
/* Constants for ffi_call_win64 */
#define STACK 0
#define PREP_ARGS_FN 32
#define ECIF 40
#define CIF_BYTES 48
#define CIF_FLAGS 56
#define RVALUE 64
#define FN 72
/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *),
extended_cif *ecif, unsigned bytes, unsigned flags,
unsigned *rvalue, void (*fn)());
*/
#ifdef _MSC_VER
PUBLIC ffi_call_win64
EXTRN __chkstk:NEAR
EXTRN ffi_closure_win64_inner:NEAR
_TEXT SEGMENT
;;; ffi_closure_win64 will be called with these registers set:
;;; rax points to 'closure'
;;; r11 contains a bit mask that specifies which of the
;;; first four parameters are float or double
;;;
;;; It must move the parameters passed in registers to their stack location,
;;; call ffi_closure_win64_inner for the actual work, then return the result.
;;;
ffi_closure_win64 PROC FRAME
;; copy register arguments onto stack
test r11, 1
jne first_is_float
mov QWORD PTR [rsp+8], rcx
jmp second
first_is_float:
movlpd QWORD PTR [rsp+8], xmm0
second:
test r11, 2
jne second_is_float
mov QWORD PTR [rsp+16], rdx
jmp third
second_is_float:
movlpd QWORD PTR [rsp+16], xmm1
third:
test r11, 4
jne third_is_float
mov QWORD PTR [rsp+24], r8
jmp fourth
third_is_float:
movlpd QWORD PTR [rsp+24], xmm2
fourth:
test r11, 8
jne fourth_is_float
mov QWORD PTR [rsp+32], r9
jmp done
fourth_is_float:
movlpd QWORD PTR [rsp+32], xmm3
done:
.ALLOCSTACK 40
sub rsp, 40
.ENDPROLOG
mov rcx, rax ; context is first parameter
mov rdx, rsp ; stack is second parameter
add rdx, 48 ; point to start of arguments
mov rax, ffi_closure_win64_inner
call rax ; call the real closure function
add rsp, 40
movd xmm0, rax ; If the closure returned a float,
; ffi_closure_win64_inner wrote it to rax
ret 0
ffi_closure_win64 ENDP
ffi_call_win64 PROC FRAME
;; copy registers onto stack
mov QWORD PTR [rsp+32], r9
mov QWORD PTR [rsp+24], r8
mov QWORD PTR [rsp+16], rdx
mov QWORD PTR [rsp+8], rcx
.PUSHREG rbp
push rbp
.ALLOCSTACK 48
sub rsp, 48 ; 00000030H
.SETFRAME rbp, 32
lea rbp, QWORD PTR [rsp+32]
.ENDPROLOG
mov eax, DWORD PTR CIF_BYTES[rbp]
add rax, 15
and rax, -16
call __chkstk
sub rsp, rax
lea rax, QWORD PTR [rsp+32]
mov QWORD PTR STACK[rbp], rax
mov rdx, QWORD PTR ECIF[rbp]
mov rcx, QWORD PTR STACK[rbp]
call QWORD PTR PREP_ARGS_FN[rbp]
mov rsp, QWORD PTR STACK[rbp]
movlpd xmm3, QWORD PTR [rsp+24]
movd r9, xmm3
movlpd xmm2, QWORD PTR [rsp+16]
movd r8, xmm2
movlpd xmm1, QWORD PTR [rsp+8]
movd rdx, xmm1
movlpd xmm0, QWORD PTR [rsp]
movd rcx, xmm0
call QWORD PTR FN[rbp]
ret_int$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_INT
jne ret_float$
mov rcx, QWORD PTR RVALUE[rbp]
mov DWORD PTR [rcx], eax
jmp SHORT ret_void$
ret_float$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT
jne SHORT ret_double$
mov rax, QWORD PTR RVALUE[rbp]
movlpd QWORD PTR [rax], xmm0
jmp SHORT ret_void$
ret_double$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE
jne SHORT ret_int64$
mov rax, QWORD PTR RVALUE[rbp]
movlpd QWORD PTR [rax], xmm0
jmp SHORT ret_void$
ret_int64$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64
jne ret_void$
mov rcx, QWORD PTR RVALUE[rbp]
mov QWORD PTR [rcx], rax
jmp SHORT ret_void$
ret_void$:
xor eax, eax
lea rsp, QWORD PTR [rbp+16]
pop rbp
ret 0
ffi_call_win64 ENDP
_TEXT ENDS
END
#else
.text
.extern ___chkstk
.extern _ffi_closure_win64_inner
# ffi_closure_win64 will be called with these registers set:
# rax points to 'closure'
# r11 contains a bit mask that specifies which of the
# first four parameters are float or double
#
# It must move the parameters passed in registers to their stack location,
# call ffi_closure_win64_inner for the actual work, then return the result.
#
.balign 16
.globl _ffi_closure_win64
_ffi_closure_win64:
# copy register arguments onto stack
test $1,%r11
jne .Lfirst_is_float
mov %rcx, 8(%rsp)
jmp .Lsecond
.Lfirst_is_float:
movlpd %xmm0, 8(%rsp)
.Lsecond:
test $2, %r11
jne .Lsecond_is_float
mov %rdx, 16(%rsp)
jmp .Lthird
.Lsecond_is_float:
movlpd %xmm1, 16(%rsp)
.Lthird:
test $4, %r11
jne .Lthird_is_float
mov %r8,24(%rsp)
jmp .Lfourth
.Lthird_is_float:
movlpd %xmm2, 24(%rsp)
.Lfourth:
test $8, %r11
jne .Lfourth_is_float
mov %r9, 32(%rsp)
jmp .Ldone
.Lfourth_is_float:
movlpd %xmm3, 32(%rsp)
.Ldone:
#.ALLOCSTACK 40
sub $40, %rsp
#.ENDPROLOG
mov %rax, %rcx # context is first parameter
mov %rsp, %rdx # stack is second parameter
add $48, %rdx # point to start of arguments
mov $_ffi_closure_win64_inner, %rax
callq *%rax # call the real closure function
add $40, %rsp
movq %rax, %xmm0 # If the closure returned a float,
# ffi_closure_win64_inner wrote it to rax
retq
.ffi_closure_win64_end:
.balign 16
.globl _ffi_call_win64
_ffi_call_win64:
# copy registers onto stack
mov %r9,32(%rsp)
mov %r8,24(%rsp)
mov %rdx,16(%rsp)
mov %rcx,8(%rsp)
#.PUSHREG rbp
push %rbp
#.ALLOCSTACK 48
sub $48,%rsp
#.SETFRAME rbp, 32
lea 32(%rsp),%rbp
#.ENDPROLOG
mov CIF_BYTES(%rbp),%eax
add $15, %rax
and $-16, %rax
callq ___chkstk
sub %rax, %rsp
lea 32(%rsp), %rax
mov %rax, STACK(%rbp)
mov ECIF(%rbp), %rdx
mov STACK(%rbp), %rcx
callq *PREP_ARGS_FN(%rbp)
mov STACK(%rbp), %rsp
movlpd 24(%rsp), %xmm3
movd %xmm3, %r9
movlpd 16(%rsp), %xmm2
movd %xmm2, %r8
movlpd 8(%rsp), %xmm1
movd %xmm1, %rdx
movlpd (%rsp), %xmm0
movd %xmm0, %rcx
callq *FN(%rbp)
.Lret_int:
cmpl $FFI_TYPE_INT, CIF_FLAGS(%rbp)
jne .Lret_float
mov RVALUE(%rbp), %rcx
mov %eax, (%rcx)
jmp .Lret_void
.Lret_float:
cmpl $FFI_TYPE_FLOAT, CIF_FLAGS(%rbp)
jne .Lret_double
mov RVALUE(%rbp), %rax
movlpd %xmm0,(%rax)
jmp .Lret_void
.Lret_double:
cmpl $FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp)
jne .Lret_int64
mov RVALUE(%rbp), %rax
movlpd %xmm0, (%rax)
jmp .Lret_void
.Lret_int64:
cmpl $FFI_TYPE_SINT64, CIF_FLAGS(%rbp)
jne .Lret_void
mov RVALUE(%rbp), %rcx
mov %rax, (%rcx)
jmp .Lret_void
.Lret_void:
xor %eax, %eax
lea 16(%rbp), %rsp
pop %rbp
retq
.ffi_call_win64_end:
#endif /* !_MSC_VER */
+2
Ver Arquivo
@@ -164,6 +164,8 @@ X86_FALSE = @X86_FALSE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
X86_WIN64_FALSE = @X86_WIN64_FALSE@
X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+32 -3
Ver Arquivo
@@ -41,7 +41,17 @@
#else
#ifdef _WIN32
#ifdef __GNUC__
#include <excpt.h>
#else
// copied from mingw header
typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER)
(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
typedef struct _EXCEPTION_REGISTRATION {
struct _EXCEPTION_REGISTRATION* prev;
PEXCEPTION_HANDLER handler;
} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;
#endif
#include <setjmp.h>
typedef struct _exc_rec {
@@ -62,13 +72,30 @@ _exc_handler(struct _EXCEPTION_RECORD* exception_record,
return ExceptionContinueExecution;
}
#ifdef _MSC_VER
#define PROTECTED_START() __try {
#define PROTECTED_END(ONERR) } __except((PROTECT)?EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH) { ONERR; }
#else
#ifdef _WIN64
// FIXME: mingw64 is untested
#define SEH_TRY(ER) \
__asm__ ("pushq %0;pushq %%gs:0;movq %%rsp,%%gs:0;" : : "g" (&(ER)))
#define SEH_CATCH(ER) \
__asm__ ("movq (%%rsp),%%rax;movq %%rax,%%gs:0;addq $16,%%rsp" : : : "%rax")
#else
#define SEH_TRY(ER) \
__asm__ ("movl %%fs:0, %0" : "=r" ((ER).ex_reg.prev)); \
__asm__ ("movl %0, %%fs:0" : : "r" (&(ER)))
#define SEH_CATCH(ER) \
__asm__ ("movl %0, %%fs:0" : : "r" ((ER).ex_reg.prev))
#endif /* !_WIN64 */
#define PROTECTED_START() \
exc_rec _er; \
int _error = 0; \
if (PROTECT) { \
_er.ex_reg.handler = _exc_handler; \
asm volatile ("movl %%fs:0, %0" : "=r" (_er.ex_reg.prev)); \
asm volatile ("movl %0, %%fs:0" : : "r" (&_er)); \
SEH_TRY(_er); \
if ((_error = setjmp(_er.buf)) != 0) { \
goto _exc_caught; \
} \
@@ -82,9 +109,11 @@ _exc_handler(struct _EXCEPTION_RECORD* exception_record,
_exc_caught: \
ONERR; \
_remove_handler: \
if (PROTECT) { asm volatile ("movl %0, %%fs:0" : : "r" (_er.ex_reg.prev)); } \
if (PROTECT) { SEH_CATCH(_er); } \
} while(0)
#endif /* !_MSC_VER */
#else // _WIN32
// Most other platforms support signals
// Catch both SIGSEGV and SIGBUS
+58 -12
Ver Arquivo
@@ -1,5 +1,17 @@
/* Standard C calling convention tests. */
/* Copyright (c) 2007-2008 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.
* <p/>
* 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.
*/
/* Native library implementation to support JUnit tests. */
#ifdef __cplusplus
extern "C" {
#endif
@@ -21,7 +33,7 @@ extern "C" {
#define int64 long long
#define LONG(X) X ## LL
#else
#error 64-bit type not defined for this platform
#error 64-bit type not defined for this compiler
#endif
#define MAGICSTRING "magic";
@@ -212,7 +224,6 @@ returnPointerArrayElement(void* args[], int which) {
EXPORT int
returnRotatedArgumentCount(char* args[]) {
int i=0;
int count = 0;
char* first = args[0];
while (args[count] != NULL) {
@@ -346,6 +357,37 @@ testStructureByValueArgument(struct CheckFieldAlignment arg) {
+ arg.int64Field + arg.floatField + arg.doubleField;
}
typedef struct ByValue8 { int8 data; } ByValue9;
typedef struct ByValue16 { int16 data; } ByValue16;
typedef struct ByValue32 { int32 data; } ByValue32;
typedef struct ByValue64 { int64 data; } ByValue64;
typedef struct ByValue128 { int64 data, data1; } ByValue128;
EXPORT int8
testStructureByValueArgument8(struct ByValue8 arg){
return arg.data;
}
EXPORT int16
testStructureByValueArgument16(struct ByValue16 arg){
return arg.data;
}
EXPORT int32
testStructureByValueArgument32(struct ByValue32 arg){
return arg.data;
}
EXPORT int64
testStructureByValueArgument64(struct ByValue64 arg){
return arg.data;
}
EXPORT int64
testStructureByValueArgument128(struct ByValue128 arg){
return arg.data + arg.data1;
}
typedef struct {
int8 field0;
int16 field1;
@@ -388,9 +430,9 @@ getStructureSize(unsigned index) {
return STRUCT_SIZES[index];
}
extern void exit(int);
extern void exit(int);
#define FIELD(T,X,N) (((T*)X)->field ## N)
#define OFFSET(T,X,N) (((char*)&FIELD(T,X,N))-((char*)&FIELD(T,X,0)))
#define OFFSET(T,X,N) (int)(((char*)&FIELD(T,X,N))-((char*)&FIELD(T,X,0)))
#define V8(N) (N+1)
#define V16(N) ((((int32)V8(N))<<8)|V8(N))
#define V32(N) ((((int32)V16(N))<<16)|V16(N))
@@ -448,7 +490,7 @@ modifyStructureArray(struct CheckFieldAlignment arg[], int length) {
EXPORT void
callVoidCallback(void (*func)()) {
callVoidCallback(void (*func)(void)) {
(*func)();
}
@@ -513,13 +555,18 @@ callStringCallback(char* (*func)(char* arg), char* arg) {
return (*func)(arg);
}
EXPORT char**
callStringArrayCallback(char** (*func)(char** arg), char** arg) {
return (*func)(arg);
}
EXPORT wchar_t*
callWideStringCallback(wchar_t* (*func)(wchar_t* arg), wchar_t* arg) {
return (*func)(arg);
}
struct cbstruct {
void (*func)();
void (*func)(void);
};
EXPORT void
@@ -545,13 +592,14 @@ structCallbackFunction(int arg1, int arg2) {
EXPORT void
setCallbackInStruct(struct cbstruct* cb) {
cb->func = (void (*)())structCallbackFunction;
cb->func = (void (*)(void))structCallbackFunction;
}
EXPORT int32
fillInt8Buffer(char *buf, int len, char value) {
int i;
for (i=0;i < len;i++) {
buf[i] = value;
}
@@ -635,17 +683,15 @@ EXPORT char *
returnStringVarArgs(const char *fmt, ...) {
char* cp;
va_list ap;
int32 sum = 0;
va_start(ap, fmt);
cp = va_arg(ap, char *);
va_end(ap);
return cp;
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(_WIN64)
///////////////////////////////////////////////////////////////////////
// stdcall tests
// All stdcall functions need to include undecorated symbols
///////////////////////////////////////////////////////////////////////
EXPORT int32 __stdcall
returnInt32ArgumentStdCall(int32 arg) {
@@ -679,7 +725,7 @@ callInt32StdCallCallback(int32 (__stdcall *func)(int32 arg, int32 arg2),
}
return value;
}
#endif /* _WIN32 */
#endif /* _WIN32 && !_WIN64 */
#ifdef __cplusplus
}
+35
Ver Arquivo
@@ -0,0 +1,35 @@
/* Copyright (c) 2007-2008 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.
* <p/>
* 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.
*/
/* Simple library with a dependency. */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
extern int returnFalse();
EXPORT int
dependentReturnFalse() {
return returnFalse();
}
#ifdef __cplusplus
}
#endif
+1 -3
Ver Arquivo
@@ -17,7 +17,6 @@ dist.dir=dist
dist.jar=${dist.dir}/jna.jar
dist.javadoc.dir=${dist.dir}/javadoc
excludes=
file.reference.jinvoke.jar=lib/jinvoke.jar
file.reference.jnalib-src=src
includes=**
jar.compress=false
@@ -30,8 +29,7 @@ javac.target=1.5
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit.classpath}:\
${file.reference.jinvoke.jar}
${libs.junit.classpath}}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=
+66
Ver Arquivo
@@ -0,0 +1,66 @@
<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>
<packaging>jar</packaging>
<version>3.0.9</version>
<name>Java Native Access</name>
<distributionManagement>
<repository>
<id>java.net-m2-repository</id>
<url>java-net:/maven2-repository/trunk/www/repository/</url>
</repository>
</distributionManagement>
<build>
<plugins>
<!-- fake out maven and install the binary artifact -->
<plugin>
<groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
<artifactId>maven-antrun-extended-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!--<ant dir="." target="dist" />-->
<attachArtifact file="dist/jna.jar" />
<attachArtifact file="dist/src-full.zip" classifier="sources" type="jar"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.jvnet.wagon-svn</groupId>
<artifactId>wagon-svn</artifactId>
<version>1.8</version>
</extension>
</extensions>
</build>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
</pluginRepository>
</pluginRepositories>
</project>
+107 -1
Ver Arquivo
@@ -1,4 +1,110 @@
<a name="top"></a>
<h2>Release 3.0.9</h2>
<b>Features</b><br>
<ul>
</ul>
<b>Bugs</b>
<ul>
<li> Fix issue 93 by only manually searching jna.library.path, then falling back to passing the mapped library name to dlopen/LoadLibrary. This fixes an issue in JRUBY (http://jira.codehaus.org/browse/JRUBY-3084) where the incorrect libc.so.6 was being loaded.
</ul>
<h2>Release 3.0.8</h2>
<b>Features</b><br>
<ul>
<li>Auto-map Pointer[]/String[]/WString[] return values.
<li>Provide utility functions to convert String to primitive array.
<li>Add jna.library.boot.path property to define the directory that the native stub library is loaded from
</ul>
<b>Bugs</b>
<ul>
</ul>
<h2>Release 3.0.7</h2>
<b>Features</b><br>
<ul>
<li>Improve win32 loading of libraries with dependencies.
</ul>
<b>Bug Fixes</b><br>
<li>Fix bug reading structures with PointerType fields, introduced with Pointer field preservation fix.
<ul></ul>
<h2>Release 3.0.6</h2>
<b>Features</b><br>
<ul>
<li>Allow arbitrary callback method names if only one method is defined in the class which implements Callback (colinwalters).
<li>Allow specification of callback type mappers by using a TYPE_MAPPER field (colinwalters).
<li>Allow uninitialized (null-valued) boxed primitives in Structures (colinwalters).
<li>Add convenience methods to set active Union field and value simultaneously (xylo).
<li>Augment Union read/writeField to set the active field.
<li>Allow Structure auto-synch across native calls to be disabled.
<li>Win64 support.
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Avoid overwriting unchanged Structure fields of type Pointer.
<li>Avoid more content dragging on OSX or warn if it's too late.
<li>Fix UnsatisfiedLinkError using transparent window on Win2K.
<li>Fix memory leak with callbacks called from native threads with no Java context (johnwallace).
<li>Defer structure size calculation if type mapper not yet set, allowing type mapper to be set in derived constructors (colinwalters).
<li>Ensure structure memory is allocated in Structure.read/writeField.
</ul>
<h2>Release 3.0.5</h2>
<b>Features</b><br>
<ul>
<li>Allow explicit declaration of field order for VMs which have an unpredictable field order.
<li>Check for w32 libraries with a "lib" prefix in addition to normal lookup.
<li>Allow String[]/WString[] as callback argument/return value (assume NULL-terminated array).
<li>Add Solaris8 compatibility to sunos-sparc build (Corey Puffalt).
<li>Look up libraries using web start library path, if appropriate (Corey Puffalt).
<li>Use constants to return integer boolean values.
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Properly track cursor on alpha-masked windows.
<li>Avoid searching /lib or /usr/lib on 64-bit Linux.
<li>Avoid using incorrect version of a library when both 32- and 64-bit versions are found.
<li>Avoid transparent window events always dragging window bug on OSX.
<li>Fix division by zero error calculating structure size on OSX/ppc.
<li>Avoid overwriting initialized NativeMapped Structure fields when calculating structure size.
<li>Fix NPE reading back into StringArray.
</ul>
<h2>Release 3.0.4</h2>
<b>Features</b><br>
<ul>
<li>Automatically write contents of Structure.ByReference fields on Structure.write().
<li>Use the actual parameter type in Function invocations if no parameter type information is available (whether method is missing or untyped varargs).
<li>Augmented X11 library mappings (xylo).
<li>Support read/write of NativeMapped arrays within Structure (notably NativeLong).
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Fix library load error when /usr/lib32 and /usr/lib both exist (linux) (Marek Slama).
<li>Avoid incorrect matches against libraries named with the same prefix
(e.g. libc-client.so vs libc.so) (xylo).
<li>Properly handle arrays of NativeMapped (e.g. NativeLong) as a Structure field (stefan endrullis).
<li>Ensure structure size calculated prior to setting union active type.
<li>XID is 64-bits on 64-bit X clients (xylo).
<li>Ensure proper arch name is used on Debian (amd64 instead of x86_64).
</ul>
<h2>Release 3.0.3</h2>
<b>Features</b><br>
<ul>
<li>Enable build/run using IBM's J9 VM (leonardo).
<li>Make StdCallFunctionMapper attempt a leading underscore if the simpler mapping doesn't work.
<li>Allow Structure.read to overwrite final fields (may not work on some 1.4 VMs).
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Fix NPE when passing an array of Structure.ByReference.
<li>Compare entire linux library version when finding a match.
<li>Don't pass struct by value unless the method signature declares it.
<li>Restrict custom first element structure alignment to OSX/ppc.
<li>Improve performance and reduce memory footprint for window masks.
Optimize polygon-based masks on w32. Use XFillRectangles on X11.
<li>Fix linkage settings on sunos-amd64 to avoid relocation errors.
<li>Fix callback allocation code on w32, solaris, freebsd, darwin (libffi was misconfigured).
<li>Fix bug when NativeMapped fields are used in a Structure.ByValue instance.
<li>Fix NPE calling Structure.read() before memory is initialized.
<li>Fix NPE calling Structure.read/write with uninitialized NativeMapped fields.
</ul>
<h2>Release 3.0.2</h2>
<b>Features</b><br>
<ul>
@@ -132,4 +238,4 @@ improved by about 2-3 orders of magnitude for large, mostly contiguous shapes
<li>Proper conversion to wchar_t on linux
<li>Copy full length of Java strings to C strings instead of stopping when a NUL
character is encountered
</ul>
</ul>
+14 -1
Ver Arquivo
@@ -12,8 +12,12 @@
*/
package com.sun.jna;
import java.util.Arrays;
import java.util.Collection;
/** All callback definitions must derive from this interface. Any
* derived interfaces must define a <code>callback</code> method.
* derived interfaces must define a single public method (which may not be named
* "hashCode", "equals", or "toString"), or one public method named "callback".
* You are responsible for deregistering your callback (if necessary)
* in its {@link Object#finalize} method. If native code attempts to call
* a callback which has been GC'd, you will likely crash the VM. If
@@ -24,5 +28,14 @@ package com.sun.jna;
* necessarily have an encompassing Java environment to catch it.
*/
public interface Callback {
/** You must this method name if your callback interface has multiple
public methods. Typically a callback will have only one such
method, in which case any method name may be used, with the exception
of those in {@link #FORBIDDEN_NAMES}.
*/
String METHOD_NAME = "callback";
/** These method names may not be used for a callback method. */
Collection FORBIDDEN_NAMES = Arrays.asList(new String[] {
"hashCode", "equals", "toString",
});
}
+71 -36
Ver Arquivo
@@ -1,4 +1,4 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
/* Copyright (c) 2007-2008 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
@@ -17,9 +17,12 @@ 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.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/** Provides a reference to an association between a native callback closure
@@ -32,8 +35,19 @@ class CallbackReference extends WeakReference {
static final Map callbackMap = new WeakHashMap();
static final Map altCallbackMap = new WeakHashMap();
private static final Map nativeStrings = new WeakHashMap();
private static final Map allocations = new WeakHashMap();
private static final Method PROXY_CALLBACK_METHOD;
static {
try {
PROXY_CALLBACK_METHOD = CallbackProxy.class.getMethod("callback", new Class[] { Object[].class });
}
catch(Exception e) {
throw new Error("Error looking up CallbackProxy.callback() method");
}
}
/** 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.
@@ -69,30 +83,17 @@ class CallbackReference extends WeakReference {
return null;
}
private static Class getCallbackClass(Class type) {
Class[] ifaces = type.getInterfaces();
for (int i=0;i < ifaces.length;i++) {
if (Callback.class.isAssignableFrom(ifaces[i])) {
type = ifaces[i];
break;
}
}
return type;
}
Pointer cbstruct;
// Keep a reference to avoid premature GC
CallbackProxy proxy;
private CallbackReference(Callback callback, int callingConvention) {
super(callback);
Class type = getCallbackClass(callback.getClass());
TypeMapper mapper = Native.getTypeMapper(type);
Method m = getCallbackMethod(callback);
TypeMapper mapper = Native.getTypeMapper(Native.findCallbackClass(callback.getClass()));
if (callback instanceof CallbackProxy) {
proxy = (CallbackProxy)callback;
}
else {
proxy = new DefaultCallbackProxy(m, mapper);
proxy = new DefaultCallbackProxy(getCallbackMethod(callback), mapper);
}
// Generate a list of parameter types that the native code can
@@ -127,8 +128,7 @@ class CallbackReference extends WeakReference {
throw new IllegalArgumentException(msg);
}
Method proxyMethod = getCallbackMethod(proxy);
cbstruct = createNativeCallback(proxy, proxyMethod,
cbstruct = createNativeCallback(proxy, PROXY_CALLBACK_METHOD,
nativeParamTypes, returnType,
callingConvention);
}
@@ -145,27 +145,50 @@ class CallbackReference extends WeakReference {
}
else if (cls == String.class
|| cls == WString.class
|| cls == String[].class
|| cls == WString[].class
|| Callback.class.isAssignableFrom(cls)) {
return Pointer.class;
}
return cls;
}
private static Method checkMethod(Method m) {
if (m.getParameterTypes().length > Function.MAX_NARGS) {
String msg = "Method signature exceeds the maximum "
+ "parameter count: " + m;
throw new IllegalArgumentException(msg);
}
return m;
}
private static Method getCallbackMethod(Callback callback) {
Method[] mlist = callback.getClass().getMethods();
for (int mi=0;mi < mlist.length;mi++) {
Method m = mlist[mi];
if (Callback.METHOD_NAME.equals(m.getName())) {
if (m.getParameterTypes().length > Function.MAX_NARGS) {
String msg = "Method signature exceeds the maximum "
+ "parameter count: " + m;
throw new IllegalArgumentException(msg);
}
return m;
// Look at only public methods defined by the Callback class
Class cls = Native.findCallbackClass(callback.getClass());
Method[] pubMethods = cls.getDeclaredMethods();
Method[] classMethods = cls.getMethods();
Set pmethods = new HashSet(Arrays.asList(pubMethods));
pmethods.retainAll(Arrays.asList(classMethods));
// Remove Object methods disallowed as callback method names
for (Iterator i=pmethods.iterator();i.hasNext();) {
Method m = (Method)i.next();
if (Callback.FORBIDDEN_NAMES.contains(m.getName())) {
i.remove();
}
}
String msg = "Callback must implement method named '"
+ Callback.METHOD_NAME + "'";
Method[] methods = (Method[])pmethods.toArray(new Method[pmethods.size()]);
if (methods.length == 1) {
return checkMethod(methods[0]);
}
for (int i=0;i < methods.length;i++) {
Method m = methods[i];
if (Callback.METHOD_NAME.equals(m.getName())) {
return checkMethod(m);
}
}
String msg = "Callback must implement a single public method, "
+ "or one public method named '" + Callback.METHOD_NAME + "'";
throw new IllegalArgumentException(msg);
}
@@ -310,6 +333,10 @@ class CallbackReference extends WeakReference {
else if (dstType == WString.class) {
value = new WString(((Pointer)value).getString(0, true));
}
else if (dstType == String[].class
|| dstType == WString[].class) {
value = ((Pointer)value).getStringArray(0, dstType == WString[].class);
}
else if (Callback.class.isAssignableFrom(dstType)) {
value = getCallback(dstType, (Pointer)value);
}
@@ -347,15 +374,23 @@ class CallbackReference extends WeakReference {
return ((Structure)value).getPointer();
}
else if (cls == boolean.class || cls == Boolean.class) {
return new Integer(Boolean.TRUE.equals(value)?-1:0);
return Boolean.TRUE.equals(value) ?
Function.INTEGER_TRUE : Function.INTEGER_FALSE;
}
else if (cls == String.class || cls == WString.class) {
// Store in a weak hash map to delay GC until string
// itself is GC'd.
NativeString ns = new NativeString(value.toString(), cls == WString.class);
nativeStrings.put(value, ns);
// Delay GC until string itself is GC'd.
allocations.put(value, ns);
return ns.getPointer();
}
else if (cls == String[].class || cls == WString.class) {
StringArray sa = cls == String[].class
? new StringArray((String[])value)
: new StringArray((WString[])value);
// Delay GC until array itself is GC'd.
allocations.put(value, sa);
return sa;
}
else if (Callback.class.isAssignableFrom(cls)) {
return getFunctionPointer((Callback)value);
}
@@ -383,7 +418,7 @@ class CallbackReference extends WeakReference {
String str = super.getName();
if (options.containsKey(Function.OPTION_INVOKING_METHOD)) {
Method m = (Method)options.get(Function.OPTION_INVOKING_METHOD);
Class cls = getCallbackClass(m.getDeclaringClass());
Class cls = Native.findCallbackClass(m.getDeclaringClass());
str += " (" + cls.getName() + ")";
}
return str;
+78 -17
Ver Arquivo
@@ -46,6 +46,9 @@ public class Function extends Pointer {
/** First alternate convention (currently used only for w32 stdcall). */
public static final int ALT_CONVENTION = 1;
static final Integer INTEGER_TRUE = new Integer(-1);
static final Integer INTEGER_FALSE = new Integer(0);
/**
* Obtain a <code>Function</code> representing a native
* function that follows the standard "C" calling convention.
@@ -239,7 +242,9 @@ public class Function extends Pointer {
continue;
if (inArg instanceof Structure) {
if (!(inArg instanceof Structure.ByValue)) {
((Structure)inArg).read();
if (((Structure)inArg).getAutoRead()) {
((Structure)inArg).read();
}
}
}
else if (args[i] instanceof PostCallRead) {
@@ -259,7 +264,9 @@ public class Function extends Pointer {
else if (Structure[].class.isAssignableFrom(inArg.getClass())) {
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
ss[si].read();
if (ss[si].getAutoRead()) {
ss[si].read();
}
}
}
}
@@ -304,7 +311,9 @@ public class Function extends Pointer {
}
else if (returnType==WString.class) {
String s = invokeString(callingConvention, args, true);
result = s != null ? new WString(s) : null;
if (s != null) {
result = new WString(s);
}
}
else if (Pointer.class.isAssignableFrom(returnType)) {
result = invokePointer(callingConvention, args);
@@ -314,7 +323,9 @@ public class Function extends Pointer {
Structure s =
invokeStructure(callingConvention, args,
Structure.newInstance(returnType));
s.read();
if (s.getAutoRead()) {
s.read();
}
result = s;
}
else {
@@ -322,7 +333,9 @@ public class Function extends Pointer {
if (result != null) {
Structure s = Structure.newInstance(returnType);
s.useMemory((Pointer)result);
s.read();
if (s.getAutoRead()) {
s.read();
}
result = s;
}
}
@@ -333,6 +346,29 @@ public class Function extends Pointer {
result = CallbackReference.getCallback(returnType, (Pointer)result);
}
}
else if (returnType==String[].class) {
Pointer p = invokePointer(callingConvention, args);
if (p != null) {
result = p.getStringArray(0);
}
}
else if (returnType==WString[].class) {
Pointer p = invokePointer(callingConvention, args);
if (p != null) {
String[] arr = p.getStringArray(0, true);
WString[] warr = new WString[arr.length];
for (int i=0;i < arr.length;i++) {
warr[i] = new WString(arr[i]);
}
result = warr;
}
}
else if (returnType==Pointer[].class) {
Pointer p = invokePointer(callingConvention, args);
if (p != null) {
result = p.getPointerArray(0);
}
}
else {
throw new IllegalArgumentException("Unsupported return type "
+ returnType
@@ -370,13 +406,34 @@ public class Function extends Pointer {
// Convert Structures to native pointers
if (arg instanceof Structure) {
Structure struct = (Structure)arg;
struct.write();
if (struct.getAutoWrite()) {
struct.write();
}
if (struct instanceof Structure.ByValue) {
return struct;
}
else {
return struct.getPointer();
// Double-check against the method signature, if available
Class ptype = struct.getClass();
if (invokingMethod != null) {
Class[] ptypes = invokingMethod.getParameterTypes();
if (isVarArgs(invokingMethod)) {
if (index < ptypes.length-1) {
ptype = ptypes[index];
}
else {
Class etype = ptypes[ptypes.length-1].getComponentType();
if (etype != Object.class) {
ptype = etype;
}
}
}
else {
ptype = ptypes[index];
}
}
if (Structure.ByValue.class.isAssignableFrom(ptype)) {
return struct;
}
}
return struct.getPointer();
}
// Convert Callback to Pointer
else if (arg instanceof Callback) {
@@ -396,7 +453,7 @@ public class Function extends Pointer {
// Default conversion of boolean to int; if you want something
// different, use a ToNativeConverter
else if (arg instanceof Boolean) {
return new Integer(Boolean.TRUE.equals(arg) ? -1 : 0);
return Boolean.TRUE.equals(arg) ? INTEGER_TRUE : INTEGER_FALSE;
}
else if (String[].class == argClass) {
return new StringArray((String[])arg);
@@ -414,7 +471,7 @@ public class Function extends Pointer {
if (byRef) {
Pointer[] pointers = new Pointer[ss.length + 1];
for (int i=0;i < ss.length;i++) {
pointers[i] = ss[i].getPointer();
pointers[i] = ss[i] != null ? ss[i].getPointer() : null;
}
return new PointerArray(pointers);
}
@@ -437,14 +494,18 @@ public class Function extends Pointer {
else {
Pointer base = ss[0].getPointer();
int size = ss[0].size();
ss[0].write();
if (ss[0].getAutoWrite()) {
ss[0].write();
}
for (int si=1;si < ss.length;si++) {
if (ss[si].getPointer().peer != base.peer + size*si) {
String msg = "Structure array elements must use"
+ " contiguous memory (at element index " + si + ")";
throw new IllegalArgumentException(msg);
}
ss[si].write();
if (ss[si].getAutoWrite()) {
ss[si].write();
}
}
return base;
}
@@ -565,8 +626,8 @@ public class Function extends Pointer {
* @param callingConvention calling convention to be used
* @param args
* Arguments to pass to the native function
* @param struct Pre-allocated structure to hold the result
* @return The native pointer returned by the target native function
* @param result Pre-allocated structure to hold the result
* @return The passed-in struct argument
*/
private native Structure invokeStructure(int callingConvention, Object[] args,
Structure result);
@@ -579,7 +640,7 @@ public class Function extends Pointer {
}
return "native function@0x" + Long.toHexString(peer);
}
/** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Pointer.class, args)}.
*/
+149 -39
Ver Arquivo
@@ -84,12 +84,7 @@ public final class Native {
/** Size of a native <code>wchar_t</code> type, in bytes. */
public static final int WCHAR_SIZE;
static {
try {
System.loadLibrary("jnidispatch");
}
catch(UnsatisfiedLinkError e) {
loadNativeLibrary();
}
loadNativeLibrary();
POINTER_SIZE = pointerSize();
LONG_SIZE = longSize();
WCHAR_SIZE = wideCharSize();
@@ -280,20 +275,17 @@ public final class Native {
* Returns whether an instance variable was instantiated.
* Expects that lock on libraries is already held
*/
private static boolean loadInstance(Class cls) {
if (libraries.containsKey(cls)) {
return true;
}
if (cls != null) {
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
// Ensure the field gets initialized by reading it
libraries.put(cls, new WeakReference(field.get(null)));
return true;
break;
}
}
}
@@ -302,25 +294,51 @@ public final class Native {
+ cls + " (" + e + ")");
}
}
return false;
}
/** Find the first instance of an interface which implements the Callback
* interface or an interface derived from Callback.
*/
static Class findCallbackClass(Class type) {
if (!Callback.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(type.getName() + " is not derived from com.sun.jna.Callback");
}
if (type.isInterface()) {
return type;
}
Class[] ifaces = type.getInterfaces();
for (int i=0;i < ifaces.length;i++) {
if (Callback.class.isAssignableFrom(ifaces[i])) {
if (ifaces[i].getMethods().length == 1)
return ifaces[i];
break;
}
}
if (Callback.class.isAssignableFrom(type.getSuperclass())) {
return findCallbackClass(type.getSuperclass());
}
return type;
}
/** Find the library interface corresponding to the given class. Checks
* all ancestor classes for a declaring class which implements
* {@link Library}.
* all ancestor classes and interfaces for a declaring class which
* implements {@link Library}.
*/
static Class findLibraryClass(Class cls) {
static Class findEnclosingLibraryClass(Class cls) {
if (cls == null) {
return null;
}
if (Library.class.isAssignableFrom(cls)) {
return cls;
}
Class fromDeclaring = findLibraryClass(cls.getDeclaringClass());
if (Callback.class.isAssignableFrom(cls)) {
cls = findCallbackClass(cls);
}
Class fromDeclaring = findEnclosingLibraryClass(cls.getDeclaringClass());
if (fromDeclaring != null) {
return fromDeclaring;
}
return findLibraryClass(cls.getSuperclass());
return findEnclosingLibraryClass(cls.getSuperclass());
}
@@ -330,13 +348,15 @@ public final class Native {
*/
public static Map getLibraryOptions(Class type) {
synchronized(libraries) {
Class interfaceClass = findLibraryClass(type);
if (interfaceClass == null)
return null;
if (!loadInstance(interfaceClass)
|| !options.containsKey(interfaceClass)) {
Class interfaceClass = findEnclosingLibraryClass(type);
if (interfaceClass != null)
loadLibraryInstance(interfaceClass);
else
interfaceClass = type;
if (!options.containsKey(interfaceClass)) {
try {
Field field = interfaceClass.getField("OPTIONS");
field.setAccessible(true);
options.put(interfaceClass, field.get(null));
}
catch (NoSuchFieldException e) {
@@ -355,13 +375,16 @@ public final class Native {
*/
public static TypeMapper getTypeMapper(Class cls) {
synchronized(libraries) {
Class interfaceClass = findLibraryClass(cls);
if (interfaceClass == null)
return null;
if (!loadInstance(interfaceClass)
|| !typeMappers.containsKey(interfaceClass)) {
Class interfaceClass = findEnclosingLibraryClass(cls);
if (interfaceClass != null)
loadLibraryInstance(interfaceClass);
else
interfaceClass = cls;
if (!typeMappers.containsKey(interfaceClass)) {
try {
Field field = interfaceClass.getField("TYPE_MAPPER");
field.setAccessible(true);
typeMappers.put(interfaceClass, field.get(null));
}
catch (NoSuchFieldException e) {
@@ -386,17 +409,19 @@ public final class Native {
*/
public static int getStructureAlignment(Class cls) {
synchronized(libraries) {
Class interfaceClass = findLibraryClass(cls);
if (interfaceClass == null)
return Structure.ALIGN_DEFAULT;
if (!loadInstance(interfaceClass)
|| !alignments.containsKey(interfaceClass)) {
Class interfaceClass = findEnclosingLibraryClass(cls);
if (interfaceClass != null)
loadLibraryInstance(interfaceClass);
else
interfaceClass = cls;
if (!alignments.containsKey(interfaceClass)) {
try {
Field field = interfaceClass.getField("STRUCTURE_ALIGNMENT");
field.setAccessible(true);
alignments.put(interfaceClass, field.get(null));
}
catch(NoSuchFieldException e) {
Map options = getLibraryOptions(cls);
Map options = getLibraryOptions(interfaceClass);
if (options != null
&& options.containsKey(Library.OPTION_STRUCTURE_ALIGNMENT)) {
alignments.put(interfaceClass, options.get(Library.OPTION_STRUCTURE_ALIGNMENT));
@@ -428,8 +453,26 @@ public final class Native {
return s.getBytes();
}
/** Obtain a NUL-terminated byte buffer equivalent to the given String. */
public static byte[] toByteArray(String s) {
byte[] bytes = getBytes(s);
byte[] buf = new byte[bytes.length+1];
System.arraycopy(bytes, 0, buf, 0, bytes.length);
return buf;
}
/** Obtain a NUL-terminated wide character buffer equivalent to the given
String.
*/
public static char[] toCharArray(String s) {
char[] chars = s.toCharArray();
char[] buf = new char[chars.length+1];
System.arraycopy(chars, 0, buf, 0, chars.length);
return buf;
}
private static String getNativeLibraryResourcePath() {
String arch = System.getProperty("os.arch");
String arch = System.getProperty("os.arch").toLowerCase();
String osPrefix;
if (Platform.isWindows()) {
osPrefix = "win32-" + arch;
@@ -438,6 +481,12 @@ public final class Native {
osPrefix = "darwin";
}
else if (Platform.isLinux()) {
if ("x86".equals(arch)) {
arch = "i386";
}
else if ("x86_64".equals(arch)) {
arch = "amd64";
}
osPrefix = "linux-" + arch;
}
else if (Platform.isSolaris()) {
@@ -454,7 +503,58 @@ public final class Native {
return "/com/sun/jna/" + osPrefix;
}
/**
* Loads the JNA stub library. It will first attempt to load this library
* from the directories specified in jna.boot.library.path. If that fails,
* it will fallback to loading from the system library paths. Finally it will
* attempt to extract the stub library from from the JNA jar file, and load it.
* <p>
* The jna.boot.library.path property is mainly to support jna.jar being
* included in -Xbootclasspath, where java.library.path and LD_LIBRARY_PATH
* are ignored. It might also be useful in other situations.
* </p>
*/
private static void loadNativeLibrary() {
String libName = "jnidispatch";
String bootPath = System.getProperty("jna.boot.library.path");
if (bootPath != null) {
String[] dirs = bootPath.split(File.pathSeparator);
for (int i = 0; i < dirs.length; ++i) {
String path = new File(new File(dirs[i]), System.mapLibraryName(libName)).getAbsolutePath();
try {
System.load(path);
return;
} catch (UnsatisfiedLinkError ex) {
}
if (Platform.isMac()) {
String orig, ext;
if (path.endsWith("dylib")) {
orig = "dylib";
ext = "jnilib";
} else {
orig = "jnilib";
ext = "dylib";
}
try {
System.load(path.substring(0, path.lastIndexOf(orig)) + ext);
return;
} catch (UnsatisfiedLinkError ex) {
}
}
}
}
try {
System.loadLibrary(libName);
}
catch(UnsatisfiedLinkError e) {
loadNativeLibraryFromJar();
}
}
/**
* Extracts and loads the JNA stub library from jna.jar
*/
private static void loadNativeLibraryFromJar() {
String libname = System.mapLibraryName("jnidispatch");
String resourceName = getNativeLibraryResourcePath() + "/" + libname;
URL url = Native.class.getResource(resourceName);
@@ -588,7 +688,8 @@ public final class Native {
* <code>jna.library.path</code> so that JNA can load libraries identified
* by the &lt;nativelib&gt; tag in the JNLP configuration file. Returns
* <code>null</code> if the Web Start native library cache location can not
* be determined.
* be determined. Note that the path returned may be different for any
* given library name.
* <p>
* Use <code>System.getProperty("javawebstart.version")</code> to detect
* whether your code is running under Web Start.
@@ -738,9 +839,18 @@ public final class Native {
/** Prints JNA library details to the console. */
public static void main(String[] args) {
final String DEFAULT_TITLE = "Java Native Access (JNA)";
final String UNKNOWN_VERSION = "unknown - package information missing";
Package pkg = Native.class.getPackage();
System.out.println(pkg.getSpecificationTitle());
System.out.println("Version: " + Native.class.getPackage().getImplementationVersion());
String title = pkg.getSpecificationTitle();
if (title == null) title = DEFAULT_TITLE;
String version = pkg.getSpecificationVersion();
if (version == null) version = UNKNOWN_VERSION;
title += " API Version " + version;
System.out.println(title);
version = pkg.getImplementationVersion();
if (version == null) version = UNKNOWN_VERSION;
System.out.println("Version: " + version);
System.out.println(" Native: " + getNativeVersion() + " ("
+ getAPIChecksum() + ")");
System.exit(0);
+142 -83
Ver Arquivo
@@ -1,5 +1,5 @@
/* Copyright (c) 2007 Wayne Meissner, 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
@@ -27,7 +27,7 @@ import java.util.Map;
import java.util.StringTokenizer;
/**
* Provides management of native library resources. One instance of this
* Provides management of native library resources. One instance of this
* class corresponds to a single loaded native library.
* <p>
* <b>Library Search Paths</b>
@@ -41,13 +41,14 @@ import java.util.StringTokenizer;
public class NativeLibrary {
private long handle;
private String libraryName;
private String libraryPath;
private final String libraryName;
private final String libraryPath;
private final Map functions = new HashMap();
private static final Map libraries = new HashMap();
private static final Map searchPaths = Collections.synchronizedMap(new HashMap());
private static final List librarySearchPath = new LinkedList();
private static final List userSearchPath = new LinkedList();
static {
// Force initialization of native library
@@ -72,10 +73,17 @@ public class NativeLibrary {
}
}
}
private static NativeLibrary loadLibrary(String libraryName) {
List searchPath = new LinkedList(librarySearchPath);
List searchPath = new LinkedList();
// Append web start path, if available. Note that this does not
// attempt any library name variations
String webstartPath = Native.getWebStartLibraryPath(libraryName);
if (webstartPath != null) {
searchPath.add(webstartPath);
}
//
// Prepend any custom search paths specifically for this library
//
@@ -85,11 +93,28 @@ public class NativeLibrary {
searchPath.addAll(0, customPaths);
}
}
searchPath.addAll(userSearchPath);
String libraryPath = findLibraryPath(libraryName, searchPath);
long handle = 0;
//
// Only search user specified paths first. This will also fall back
// to dlopen/LoadLibrary() since findLibraryPath returns the mapped name
// if it cannot find the library.
//
try {
handle = open(libraryPath);
}
catch(UnsatisfiedLinkError e) {
// Add the system paths back for all fallback searching
searchPath.addAll(librarySearchPath);
}
try {
if (handle == 0) {
libraryPath = findLibraryPath(libraryName, searchPath);
handle = open(libraryPath);
}
}
catch(UnsatisfiedLinkError e) {
if (Platform.isLinux()) {
//
@@ -110,6 +135,12 @@ public class NativeLibrary {
catch(UnsatisfiedLinkError e2) { e = e2; }
}
}
// Try the same library with a "lib" prefix
else if (Platform.isWindows()) {
libraryPath = findLibraryPath("lib" + libraryName, searchPath);
try { handle = open(libraryPath); }
catch(UnsatisfiedLinkError e2) { e = e2; }
}
if (handle == 0) {
throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': "
+ e.getMessage());
@@ -117,7 +148,7 @@ public class NativeLibrary {
}
return new NativeLibrary(libraryName, libraryPath, handle);
}
private String getLibraryName(String libraryName) {
String simplified = libraryName;
final String BASE = "---";
@@ -133,16 +164,16 @@ public class NativeLibrary {
}
return simplified;
}
/**
* Returns an instance of NativeLibrary for the specified name.
* The library is loaded if not already loaded. If already loaded, the
* Returns an instance of NativeLibrary for the specified name.
* The library is loaded if not already loaded. If already loaded, the
* existing instance is returned.<p>
* More than one name may map to the same NativeLibrary instance; only
* a single instance will be provided for any given unique file path.
*
*
* @param libraryName The library name to load.
* This can be short form (e.g. "c"),
* This can be short form (e.g. "c"),
* an explicit version (e.g. "libc.so.6"), or
* the full path to the library (e.g. "/lib/libc.so.6").
*/
@@ -163,13 +194,13 @@ public class NativeLibrary {
return library;
}
}
/**
* Add a path to search for the specified library, ahead of any system paths
*
*
* @param libraryName The name of the library to use the path for
* @param path The path to use when trying to load the library
*/
*/
public static final void addSearchPath(String libraryName, String path) {
synchronized (searchPaths) {
List customPaths = (List) searchPaths.get(libraryName);
@@ -177,7 +208,7 @@ public class NativeLibrary {
customPaths = Collections.synchronizedList(new LinkedList());
searchPaths.put(libraryName, customPaths);
}
customPaths.add(path);
}
}
@@ -196,7 +227,7 @@ public class NativeLibrary {
public Function getFunction(String functionName) {
return getFunction(functionName, Function.C_CONVENTION);
}
/**
* Create a new @{link Function} that is linked with a native
* function that follows a given calling convention.
@@ -226,19 +257,19 @@ public class NativeLibrary {
/** Look up the given global variable within this library.
* @param symbolName
* @return Pointer representing the global variable address
* @throws UnsatisfiedLinkError if the symbol is not found
* @throws UnsatisfiedLinkError if the symbol is not found
*/
public Pointer getGlobalVariableAddress(String symbolName) {
try {
return new Pointer(getSymbolAddress(symbolName));
}
catch(UnsatisfiedLinkError e) {
throw new UnsatisfiedLinkError("Error looking up '"
+ symbolName + "': "
throw new UnsatisfiedLinkError("Error looking up '"
+ symbolName + "': "
+ e.getMessage());
}
}
/**
* Used by the Function class to locate a symbol
* @throws UnsatisfiedLinkError if the symbol can't be found
@@ -256,7 +287,7 @@ public class NativeLibrary {
public String getName() {
return libraryName;
}
/** Returns the file on disk corresponding to this NativeLibrary instacne.
/** Returns the file on disk corresponding to this NativeLibrary instacne.
*/
public File getFile() {
return new File(libraryPath);
@@ -265,7 +296,7 @@ public class NativeLibrary {
protected void finalize() {
dispose();
}
public void dispose() {
synchronized(libraries) {
libraries.remove(getName());
@@ -279,7 +310,7 @@ public class NativeLibrary {
}
}
}
private static List initPaths(String key) {
String value = System.getProperty(key, "");
if ("".equals(value)) {
@@ -295,22 +326,22 @@ public class NativeLibrary {
}
return list;
}
/** Use standard library search paths to find the library. */
private static String findLibraryPath(String libName, List searchPath) {
//
// If a full path to the library was specified, don't search for it
//
if (new File(libName).isAbsolute()) {
return libName;
}
//
// Get the system name for the library (e.g. libfoo.so)
//
String name = mapLibraryName(libName);
// Search in the JNA paths for it
for (Iterator it = searchPath.iterator(); it.hasNext(); ) {
File file = new File(new File((String) it.next()), name);
@@ -318,7 +349,7 @@ public class NativeLibrary {
return file.getAbsolutePath();
}
}
//
// Default to returning the mapped library name and letting the system
// search for it
@@ -326,31 +357,32 @@ public class NativeLibrary {
return name;
}
private static String mapLibraryName(String libName) {
if (Platform.isMac()) {
if (libName.startsWith("lib")
&& (libName.endsWith(".dylib") || libName.endsWith(".jnilib"))) {
&& (libName.endsWith(".dylib")
|| libName.endsWith(".jnilib"))) {
return libName;
}
String name = System.mapLibraryName(libName);
// On MacOSX, System.mapLibraryName() returns the .jnilib extension
// (the suffix for JNI libraries); ordinarily shared libraries have
// (the suffix for JNI libraries); ordinarily shared libraries have
// a .dylib suffix
if (name.endsWith(".jnilib")) {
return name.substring(0, name.lastIndexOf(".jnilib")) + ".dylib";
}
return name;
}
}
else if (Platform.isLinux()) {
if (isVersionedName(libName)) {
// A specific version was requested - use as is for search
return libName;
}
}
}
return System.mapLibraryName(libName);
}
private static boolean isVersionedName(String name) {
if (name.startsWith("lib")) {
int so = name.lastIndexOf(".so.");
@@ -366,26 +398,26 @@ public class NativeLibrary {
}
return false;
}
/**
* matchLibrary() is very Linux specific. It is here to deal with the case
* where /usr/lib/libc.so does not exist, or it is not a valid symlink to
* a versioned file (e.g. /lib/libc.so.6).
*/
static String matchLibrary(final String libName, List searchPath) {
File lib = new File(libName);
File lib = new File(libName);
if (lib.isAbsolute()) {
searchPath = Arrays.asList(new String[] { lib.getParent() });
searchPath = Arrays.asList(new String[] { lib.getParent() });
}
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.startsWith("lib" + libName)
|| (name.startsWith(libName)
&& libName.startsWith("lib")))
&& isVersionedName(name);
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(); ) {
File[] files = new File((String) it.next()).listFiles(filter);
@@ -393,31 +425,56 @@ public class NativeLibrary {
matches.addAll(Arrays.asList(files));
}
}
//
// Search through the results and return the highest numbered version
// i.e. libc.so.6 is preferred over libc.so.5
//
int version = 0;
double bestVersion = -1;
String bestMatch = null;
for (Iterator it = matches.iterator(); it.hasNext(); ) {
String path = ((File) it.next()).getAbsolutePath();
String num = path.substring(path.lastIndexOf('.') + 1);
try {
if (Integer.parseInt(num) >= version) {
bestMatch = path;
}
} catch (NumberFormatException e) {} // Just skip if not a number
String ver = path.substring(path.lastIndexOf(".so.") + 4);
double version = parseVersion(ver);
if (version > bestVersion) {
bestVersion = version;
bestMatch = path;
}
}
return bestMatch;
}
static double parseVersion(String ver) {
double v = 0;
double divisor = 1;
int dot = ver.indexOf(".");
while (ver != null) {
String num;
if (dot != -1) {
num = ver.substring(0, dot);
ver = ver.substring(dot + 1);
dot = ver.indexOf(".");
}
else {
num = ver;
ver = null;
}
try {
v += Integer.parseInt(num) / divisor;
}
catch(NumberFormatException e) {
return 0;
}
divisor *= 100;
}
return v;
}
private static native long open(String name);
private static native void close(long handle);
private static native long findSymbol(long handle, String name);
static {
librarySearchPath.addAll(initPaths("jna.library.path"));
userSearchPath.addAll(initPaths("jna.library.path"));
String webstartPath = Native.getWebStartLibraryPath("jnidispatch");
if (webstartPath != null) {
librarySearchPath.add(webstartPath);
@@ -428,13 +485,15 @@ public class NativeLibrary {
String platformPath = "";
String sep = "";
String archPath = "";
//
// Search first for an arch specific path, but fall back to the generic
// path if it does not exist. Some older linux amd64 distros did not
// have /usr/lib64, and 32bit distros only have /usr/lib.
// FreeBSD also only has /usr/lib by default, with /usr/lib32 for 32bit compat.
// Solaris seems to have both, but defaults to 32bit userland even on
// Search first for an arch specific path if one exists, but always
// include the generic paths if they exist.
// NOTES (wmeissner):
// Some older linux amd64 distros did not have /usr/lib64, and 32bit
// distros only have /usr/lib. FreeBSD also only has /usr/lib by
// default, with /usr/lib32 for 32bit compat.
// Solaris seems to have both, but defaults to 32bit userland even on
// 64bit machines, so we have to explicitly search the 64bit one when
// running a 64bit JVM.
//
@@ -442,25 +501,25 @@ public class NativeLibrary {
// Linux & FreeBSD use /usr/lib32, solaris uses /usr/lib/32
archPath = (Platform.isSolaris() ? "/" : "") + Pointer.SIZE * 8;
}
if (new File("/usr/lib" + archPath).exists()) {
platformPath += sep + "/usr/lib" + archPath;
sep = File.pathSeparator;
String[] paths = {
"/usr/lib" + archPath,
"/lib" + archPath,
"/usr/lib",
"/lib",
};
// Linux 64-bit does not use /lib or /usr/lib
if (Platform.isLinux() && Pointer.SIZE == 8) {
paths = new String[] {
"/usr/lib" + archPath,
"/lib" + archPath,
};
}
// Use default if arch specific is not found
else if (new File("/usr/lib").exists()) {
platformPath += sep + "/usr/lib";
sep = File.pathSeparator;
}
if (new File("/lib" + archPath).exists()) {
platformPath += sep + "/lib" + archPath;
sep = File.pathSeparator;
}
// Use default if arch specific is not found
else if (new File("/lib").exists()) {
platformPath += sep + "/lib";
sep = File.pathSeparator;
for (int i=0;i < paths.length;i++) {
File dir = new File(paths[i]);
if (dir.exists() && dir.isDirectory()) {
platformPath += sep + paths[i];
sep = File.pathSeparator;
}
}
if (!"".equals(platformPath)) {
System.setProperty("jna.platform.library.path", platformPath);
+10 -11
Ver Arquivo
@@ -1,28 +1,27 @@
/* 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;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
/** Provides type conversion for instances of {@link NativeMapped}. */
public class NativeMappedConverter implements TypeConverter {
private static Map converters = new WeakHashMap();
private Class type;
private Class nativeType;
private NativeMapped instance;
private final Class type;
private final Class nativeType;
private final NativeMapped instance;
public static NativeMappedConverter getInstance(Class cls) {
synchronized(converters) {
NativeMappedConverter nmc = (NativeMappedConverter)converters.get(cls);
@@ -33,7 +32,7 @@ public class NativeMappedConverter implements TypeConverter {
return nmc;
}
}
public NativeMappedConverter(Class type) {
if (!NativeMapped.class.isAssignableFrom(type))
throw new IllegalArgumentException("Type must derive from "
@@ -42,7 +41,7 @@ public class NativeMappedConverter implements TypeConverter {
this.instance = defaultValue();
this.nativeType = instance.nativeType();
}
public NativeMapped defaultValue() {
try {
return (NativeMapped)type.newInstance();
@@ -67,6 +66,6 @@ public class NativeMappedConverter implements TypeConverter {
}
public Object toNative(Object value, ToNativeContext context) {
return value == null ? null : ((NativeMapped)value).toNative();
return value == null ? defaultValue().toNative() : ((NativeMapped)value).toNative();
}
}
+8 -1
Ver Arquivo
@@ -17,7 +17,8 @@ public final class Platform {
private static final int WINDOWS = 2;
private static final int SOLARIS = 3;
private static final int FREEBSD = 4;
private static final int WINDOWSCE = 5;
private static final int OPENBSD = 5;
private static final int WINDOWSCE = 6;
private static final int osType;
static {
@@ -40,6 +41,9 @@ public final class Platform {
else if (osName.startsWith("FreeBSD")) {
osType = FREEBSD;
}
else if (osName.startsWith("OpenBSD")) {
osType = OPENBSD;
}
else {
osType = UNSPECIFIED;
}
@@ -63,6 +67,9 @@ public final class Platform {
public static final boolean isFreeBSD() {
return osType == FREEBSD;
}
public static final boolean isOpenBSD() {
return osType == OPENBSD;
}
public static final boolean isX11() {
// TODO: check filesystem for /usr/X11 or some other X11-specific test
return !Platform.isWindows() && !Platform.isMac();
+97 -54
Ver Arquivo
@@ -13,6 +13,8 @@ package com.sun.jna;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
/**
* An abstraction for a native pointer data type. A Pointer instance
@@ -112,12 +114,12 @@ public class Pointer {
}
private static native long _indexOf(long addr, byte value);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>byte</code> array into which data is copied
* @param index array index from which to start copying
* @param length number of elements from native pointer that must be copied
@@ -125,15 +127,15 @@ public class Pointer {
public void read(long offset, byte[] buf, int index, int length) {
_read(peer + offset, buf, index, length);
}
private static native void _read(long addr, byte[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>short</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -141,15 +143,15 @@ public class Pointer {
public void read(long offset, short[] buf, int index, int length) {
_read(peer + offset, buf, index, length);
}
private static native void _read(long addr, short[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>char</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -162,10 +164,10 @@ public class Pointer {
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>int</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -175,12 +177,12 @@ public class Pointer {
}
private static native void _read(long addr, int[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>long</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -192,10 +194,10 @@ public class Pointer {
private static native void _read(long addr, long[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>float</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -203,14 +205,14 @@ public class Pointer {
public void read(long offset, float[] buf, int index, int length) {
_read(peer + offset, buf, index, length);
}
private static native void _read(long addr, float[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf <code>double</code> array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -218,14 +220,14 @@ public class Pointer {
public void read(long offset, double[] buf, int index, int length) {
_read(peer + offset, buf, index, length);
}
private static native void _read(long addr, double[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* Indirect the native pointer, copying <em>from</em> memory pointed to by
* native pointer, into the specified array.
*
* @param offset byte offset from pointer from which data is copied
* @param offset byte offset from pointer from which data is copied
* @param buf {@link Pointer} array into which data is copied
* @param index array index to which data is copied
* @param length number of elements from native pointer that must be copied
@@ -242,10 +244,10 @@ public class Pointer {
//////////////////////////////////////////////////////////////////////////
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>byte</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -254,15 +256,15 @@ public class Pointer {
public void write(long offset, byte[] buf, int index, int length) {
_write(peer + offset, buf, index, length);
}
private static native void _write(long addr, byte[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>short</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -275,10 +277,10 @@ public class Pointer {
private static native void _write(long addr, short[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>char</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -291,10 +293,10 @@ public class Pointer {
private static native void _write(long addr, char[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>int</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -310,7 +312,7 @@ public class Pointer {
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>long</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -323,10 +325,10 @@ public class Pointer {
private static native void _write(long addr, long[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>float</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -339,10 +341,10 @@ public class Pointer {
private static native void _write(long addr, float[] buf, int index, int length);
/**
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* Indirect the native pointer, copying <em>into</em> memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
* @param offset byte offset from pointer into which data is copied
* @param buf <code>double</code> array from which to copy
* @param index array index from which to start copying
* @param length number of elements from <code>buf</code> that must be
@@ -354,7 +356,7 @@ public class Pointer {
private static native void _write(long addr, double[] buf, int index, int length);
/** Write the given array of Pointer to native memory.
/** Write the given array of Pointer to native memory.
* @param bOff byte offset from pointer into which data is copied
* @param buf <code>Pointer</code> array from which to copy
* @param index array index from which to start copying
@@ -366,14 +368,14 @@ public class Pointer {
setPointer(bOff + i * Pointer.SIZE, buf[index + i]);
}
}
//////////////////////////////////////////////////////////////////////////
// Java type read methods
//////////////////////////////////////////////////////////////////////////
/**
* Indirect the native pointer as a pointer to <code>byte</code>. This is
* equivalent to the expression
* equivalent to the expression
* <code>*((jbyte *)((char *)Pointer + offset))</code>.
*
* @param offset offset from pointer to perform the indirection
@@ -382,12 +384,12 @@ public class Pointer {
public byte getByte(long offset) {
return _getByte(peer + offset);
}
private static native byte _getByte(long addr);
/**
* Indirect the native pointer as a pointer to <code>wchar_t</code>. This
* is equivalent to the expression
* Indirect the native pointer as a pointer to <code>wchar_t</code>. This
* is equivalent to the expression
* <code>*((wchar_t*)((char *)Pointer + offset))</code>.
*
* @param offset offset from pointer to perform the indirection
@@ -396,7 +398,7 @@ public class Pointer {
public char getChar(long offset) {
return _getChar(peer + offset);
}
private static native char _getChar(long addr);
/**
@@ -452,7 +454,7 @@ public class Pointer {
public NativeLong getNativeLong(long offset) {
return new NativeLong(NativeLong.SIZE == 8 ? getLong(offset) : getInt(offset));
}
/**
* Indirect the native pointer as a pointer to <code>float</code>. This is
* equivalent to the expression
@@ -468,7 +470,7 @@ public class Pointer {
private native float _getFloat(long addr);
/**
* Indirect the native pointer as a pointer to <code>double</code>. This
* Indirect the native pointer as a pointer to <code>double</code>. This
* is equivalent to the expression
* <code>*((jdouble *)((char *)Pointer + offset))</code>.
*
@@ -478,18 +480,18 @@ public class Pointer {
public double getDouble(long offset) {
return _getDouble(peer + offset);
}
private static native double _getDouble(long addr);
/**
* Indirect the native pointer as a pointer to pointer. This is equivalent
* to the expression
* Indirect the native pointer as a pointer to pointer. This is equivalent
* to the expression
* <code>*((void **)((char *)Pointer + offset))</code>.
*
* @param offset byte offset from pointer to perform the indirection
* @return a {@link Pointer} equivalent of the pointer value
* being pointed to, or <code>null</code> if the pointer value is
* <code>NULL</code>;
* @return a {@link Pointer} equivalent of the pointer value
* being pointed to, or <code>null</code> if the pointer value is
* <code>NULL</code>;
*/
public Pointer getPointer(long offset) {
return _getPointer(peer + offset);
@@ -503,16 +505,16 @@ public class Pointer {
*
* @param offset byte offset from pointer to start the buffer
* @param length Length of ByteBuffer
* @return a direct ByteBuffer that accesses the memory being pointed to,
* @return a direct ByteBuffer that accesses the memory being pointed to,
*/
public ByteBuffer getByteBuffer(long offset, long length) {
return _getDirectByteBuffer(peer + offset, length).order(ByteOrder.nativeOrder());
}
/**
* Get a direct ByteBuffer mapped to the memory pointed to by the pointer.
*
* @param offset byte offset from pointer to start the buffer
* @param addr byte offset from pointer to start the buffer
* @param length Length of ByteBuffer
* @return a direct ByteBuffer that accesses the memory being pointed to,
*/
@@ -603,12 +605,53 @@ v * @param wide whether to convert from a wide or standard C string
return buf;
}
/** Returns an array of {@link Pointer}. The array length is
* determined by a NULL-valued terminating element.
*/
public Pointer[] getPointerArray(long base) {
List array = new ArrayList();
int offset = 0;
Pointer p = getPointer(base);
while (p != null) {
array.add(p);
offset += Pointer.SIZE;
p = getPointer(base + offset);
}
return (Pointer[])array.toArray(new Pointer[array.size()]);
}
/** Returns an array of {@link Pointer} of the requested size. */
public Pointer[] getPointerArray(long offset, int arraySize) {
Pointer[] buf = new Pointer[arraySize];
read(offset, buf, 0, arraySize);
return buf;
}
/** Returns an array of <code>String</code> based on a native array
* of <code>char *</code>. The array length is determined by a
* NULL-valued terminating element.
*/
public String[] getStringArray(long base) {
return getStringArray(base, false);
}
/** Returns an array of <code>String</code> based on a native array
* of <code>char*</code> or <code>wchar_t*</code> based on the
* <code>wide</code> parameter. The array length is determined by a
* NULL-valued terminating element.
*/
public String[] getStringArray(long base, boolean wide) {
List strings = new ArrayList();
int offset = 0;
Pointer p = getPointer(base);
while (p != null) {
strings.add(p.getString(0, wide));
offset += SIZE;
p = getPointer(base + offset);
}
return (String[])strings.toArray(new String[strings.size()]);
}
//////////////////////////////////////////////////////////////////////////
// Java type write methods
//////////////////////////////////////////////////////////////////////////
+19 -2
Ver Arquivo
@@ -1,3 +1,15 @@
/* Copyright (c) 2007-2008 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.
* <p/>
* 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.
*/
package com.sun.jna;
import java.util.ArrayList;
@@ -43,8 +55,13 @@ public class StringArray extends Memory implements Function.PostCallRead {
public void read() {
boolean returnWide = original instanceof WString[];
for (int si=0;si < original.length;si++) {
String s = getPointer(si * Pointer.SIZE).getString(0, wide);
original[si] = returnWide ? new WString(s) : (Object)s;
Pointer p = getPointer(si * Pointer.SIZE);
Object s = null;
if (p != null) {
s = p.getString(0, wide);
if (returnWide) s = new WString((String)s);
}
original[si] = s;
}
}
}
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+109
Ver Arquivo
@@ -39,11 +39,20 @@ public abstract class Union extends Structure {
protected Union(int size, int alignType) {
super(size, alignType);
}
/** Create a Union of the given size and alignment type. */
protected Union(TypeMapper mapper) {
super(mapper);
}
/** Create a Union of the given size and alignment type. */
protected Union(int size, int alignType, TypeMapper mapper) {
super(size, alignType, mapper);
}
/** Indicates which field will be used to write to native memory.
* @throws IllegalArgumentException if the type does not correspond to
* any declared union field.
*/
public void setType(Class type) {
ensureAllocated();
for (Iterator i=fields().values().iterator();i.hasNext();) {
StructField f = (StructField)i.next();
if (f.type == type) {
@@ -54,6 +63,106 @@ public abstract class Union extends Structure {
throw new IllegalArgumentException("No field of type " + type + " in " + this);
}
/** Force a read of the given field from native memory.
* @return the new field value, after updating
* @throws IllegalArgumentException if no field exists with the given name
*/
public Object readField(String name) {
ensureAllocated();
StructField f = (StructField)fields().get(name);
if (f != null) {
setType(f.type);
}
return super.readField(name);
}
/** Write the given field value to native memory.
* The given field will become the active one.
* @throws IllegalArgumentException if no field exists with the given name
*/
public void writeField(String name) {
ensureAllocated();
StructField f = (StructField)fields().get(name);
if (f != null) {
setType(f.type);
}
super.writeField(name);
}
/** Write the given field value to the field and native memory.
* The given field will become the active one.
* @throws IllegalArgumentException if no field exists with the given name
*/
public void writeField(String name, Object value) {
ensureAllocated();
StructField f = (StructField)fields().get(name);
if (f != null) {
setType(f.type);
}
super.writeField(name, value);
}
/** Reads the Structure field of the given type from memory, sets it as
* the active type and returns it. Convenience method for
* <pre><code>
* Union u;
* Class type;
* u.setType(type);
* u.read();
* value = u.<i>field</i>;
* </code></pre>
* @param type class type of the Structure field to read
* @return the Structure field with the given type
*/
public Object getTypedValue(Class type) {
ensureAllocated();
for (Iterator i=fields().values().iterator();i.hasNext();) {
StructField f = (StructField)i.next();
if (f.type == type) {
activeField = f;
read();
return getField(activeField);
}
}
throw new IllegalArgumentException("No field of type " + type + " in " + this);
}
/** Set the active type and its value. Convenience method for
* <pre><code>
* Union u;
* Class type;
* u.setType(type);
* u.<i>field</i> = value;
* </code></pre>
* @param object instance of a class which is part of the union
* @return this Union object
*/
public Object setTypedValue(Object object) {
ensureAllocated();
StructField f = findField(object.getClass());
if (f != null) {
activeField = f;
setField(f, object);
return this;
}
throw new IllegalArgumentException("No field of type " + object.getClass() + " in " + this);
}
/** Returns the field in this union with the same type as <code>type</code>,
* if any, null otherwise.
* @param type type to search for
* @return StructField of matching type
*/
private StructField findField(Class type) {
for (Iterator i=fields().values().iterator();i.hasNext();) {
StructField f = (StructField)i.next();
if (f.type.isAssignableFrom(type)) {
return f;
}
}
return null;
}
/** Only the currently selected field will be written. */
void writeField(StructField field) {
if (field == activeField) {
@@ -10,6 +10,7 @@
*/
package com.sun.jna.examples;
import java.awt.Cursor;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
@@ -51,16 +52,11 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
// TODO: put this into a reasonable API; right now this is pretty much
// just hard-coded blitting of an image into a window
// Thanks to Rui Lopes for the C# example on which this is based:
// rui@ruilopes.com
// http://www.codeproject.com/cs/media/perpxalpha_sharp.asp?df=100&forumid=3270&exp=0&select=773155
public class AlphaMaskDemo2 implements Runnable {
private static final DataFlavor URL_FLAVOR = new DataFlavor("application/x-java-url; class=java.net.URL",
"URL");
private static final DataFlavor URI_LIST_FLAVOR = new DataFlavor("text/uri-list; class=java.lang.String",
"URI list");
private static final DataFlavor URL_FLAVOR =
new DataFlavor("application/x-java-url; class=java.net.URL", "URL");
private static final DataFlavor URI_LIST_FLAVOR =
new DataFlavor("text/uri-list; class=java.lang.String", "URI list");
private JFrame frame;
private JWindow alphaWindow;
private JLabel icon;
@@ -107,6 +103,7 @@ public class AlphaMaskDemo2 implements Runnable {
frame = new JFrame("Alpha Mask Demo");
alphaWindow = new JWindow(frame, gconfig);
icon = new JLabel();
icon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
alphaWindow.getContentPane().add(icon);
JButton quit = new JButton("Quit");
JLabel label = new JLabel("Drag this window by its image");
@@ -252,6 +249,7 @@ public class AlphaMaskDemo2 implements Runnable {
"<html><center>Drop an image with an alpha channel onto this window<br>"
+ "You may also adjust the overall transparency with the slider</center></html>"),
BorderLayout.NORTH);
p.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
final JSlider slider = new JSlider(0, 255, 255);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
+42 -18
Ver Arquivo
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.sun.jna.Pointer;
import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.examples.win32.Kernel32.FILE_NOTIFY_INFORMATION;
import com.sun.jna.examples.win32.Kernel32.OVERLAPPED;
@@ -56,8 +55,8 @@ public abstract class FileMonitor {
}
public class FileEvent extends EventObject {
private File file;
private int type;
private final File file;
private final int type;
public FileEvent(File file, int type) {
super(FileMonitor.this);
this.file = file;
@@ -70,7 +69,7 @@ public abstract class FileMonitor {
}
}
private Map watched = new HashMap();
private final Map watched = new HashMap();
private List listeners = new ArrayList();
protected abstract void watch(File file, int mask, boolean recursive) throws IOException ;
@@ -143,13 +142,13 @@ public abstract class FileMonitor {
private static final int BUFFER_SIZE = 4096;
private class FileInfo {
public File file;
public HANDLE handle;
public int notifyMask;
public boolean recursive;
public FILE_NOTIFY_INFORMATION info = new FILE_NOTIFY_INFORMATION(BUFFER_SIZE);
public IntByReference infoLength = new IntByReference();
public OVERLAPPED overlapped = new OVERLAPPED();
public final File file;
public final HANDLE handle;
public final int notifyMask;
public final boolean recursive;
public final FILE_NOTIFY_INFORMATION info = new FILE_NOTIFY_INFORMATION(BUFFER_SIZE);
public final IntByReference infoLength = new IntByReference();
public final OVERLAPPED overlapped = new OVERLAPPED();
public FileInfo(File f, HANDLE h, int mask, boolean recurse) {
this.file = f;
this.handle = h;
@@ -159,8 +158,8 @@ public abstract class FileMonitor {
}
private Thread watcher;
private HANDLE port;
private Map fileMap = new HashMap();
private Map handleMap = new HashMap();
private final Map fileMap = new HashMap();
private final Map handleMap = new HashMap();
private void handleChanges(FileInfo finfo) throws IOException {
Kernel32 klib = Kernel32.INSTANCE;
@@ -212,7 +211,10 @@ public abstract class FileMonitor {
HANDLEByReference rkey = new HANDLEByReference();
PointerByReference roverlap = new PointerByReference();
klib.GetQueuedCompletionStatus(port, rcount, rkey, roverlap, Kernel32.INFINITE);
return (FileInfo)handleMap.get(rkey.getValue());
synchronized (this) {
return (FileInfo)handleMap.get(rkey.getValue());
}
}
private int convertMask(int mask) {
int result = 0;
@@ -220,7 +222,7 @@ public abstract class FileMonitor {
result |= Kernel32.FILE_NOTIFY_CHANGE_CREATION;
}
if ((mask & FILE_DELETED) != 0) {
result |= Kernel32.FILE_NOTIFY_CHANGE_CREATION;
result |= Kernel32.FILE_NOTIFY_CHANGE_NAME;
}
if ((mask & FILE_MODIFIED) != 0) {
result |= Kernel32.FILE_NOTIFY_CHANGE_LAST_WRITE;
@@ -242,6 +244,9 @@ public abstract class FileMonitor {
}
return result;
}
private static int watcherThreadID;
protected synchronized void watch(File file, int eventMask, boolean recursive) throws IOException {
File dir = file;
if (!dir.isDirectory()) {
@@ -286,15 +291,26 @@ public abstract class FileMonitor {
finfo.overlapped, null)) {
int err = klib.GetLastError();
throw new IOException("ReadDirectoryChangesW failed on "
+ finfo.file
+ finfo.file + ", handle " + handle
+ ": '" + getSystemError(err)
+ "' (" + err + ")");
}
if (watcher == null) {
watcher = new Thread("W32 File Monitor") {
watcher = new Thread("W32 File Monitor-" + (watcherThreadID++)) {
public void run() {
FileInfo finfo;
while ((finfo = waitForChange()) != null) {
while (true) {
finfo = waitForChange();
if (finfo == null) {
synchronized(W32FileMonitor.this) {
if (fileMap.isEmpty()) {
watcher = null;
break;
}
}
continue;
}
try {
handleChanges(finfo);
}
@@ -309,6 +325,7 @@ public abstract class FileMonitor {
watcher.start();
}
}
protected synchronized void unwatch(File file) {
FileInfo finfo = (FileInfo)fileMap.remove(file);
if (finfo != null) {
@@ -318,6 +335,12 @@ public abstract class FileMonitor {
}
}
protected synchronized void dispose() {
// unwatch any remaining files in map, allows watcher thread to exit
int i = 0;
for (Object[] keys = fileMap.keySet().toArray(); !fileMap.isEmpty();) {
unwatch((File)keys[i++]);
}
Kernel32 klib = Kernel32.INSTANCE;
klib.PostQueuedCompletionStatus(port, 0, null, null);
klib.CloseHandle(port);
@@ -333,6 +356,7 @@ public abstract class FileMonitor {
null, code,
0, pref, 0, null);
String s = pref.getValue().getString(0, !Boolean.getBoolean("w32.ascii"));
s = s.replace(".\r",".").replace(".\n",".");
lib.LocalFree(pref.getValue());
return s;
}
+44 -27
Ver Arquivo
@@ -13,6 +13,9 @@
package com.sun.jna.examples;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import com.sun.jna.examples.win32.Shell32;
import com.sun.jna.examples.win32.Shell32.SHFILEOPSTRUCT;
@@ -24,9 +27,9 @@ public abstract class FileUtils {
}
/** Move the given file to the system trash, if one is available.
Returns whether the operation was successful.
Throws an exception on failure.
*/
public abstract boolean moveToTrash(File[] files);
public abstract void moveToTrash(File[] files) throws IOException;
/** Canonical lazy loading of a singleton. */
private static class Holder {
@@ -53,7 +56,7 @@ public abstract class FileUtils {
public boolean hasTrash() { return true; }
public boolean moveToTrash(File[] files) {
public void moveToTrash(File[] files) throws IOException {
Shell32 shell = Shell32.INSTANCE;
SHFILEOPSTRUCT fileop = new SHFILEOPSTRUCT();
fileop.wFunc = Shell32.FO_DELETE;
@@ -63,7 +66,13 @@ public abstract class FileUtils {
}
fileop.pFrom = fileop.encodePaths(paths);
fileop.fFlags = Shell32.FOF_ALLOWUNDO|Shell32.FOF_NOCONFIRMATION|Shell32.FOF_SILENT;
return shell.SHFileOperation(fileop) == 0;
int ret = shell.SHFileOperation(fileop);
if (ret != 0) {
throw new IOException("Move to trash failed: " + ret);
}
if (fileop.fAnyOperationsAborted) {
throw new IOException("Move to trash aborted");
}
}
}
@@ -71,22 +80,24 @@ public abstract class FileUtils {
public boolean hasTrash() { return true; }
public boolean moveToTrash(File[] files) {
public void moveToTrash(File[] files) throws IOException {
// TODO: use native API for moving to trash (if any)
File home = new File(System.getProperty("user.home"));
File trash = new File(home, ".Trash");
if (trash.exists()) {
boolean success = true;
for (int i=0;i < files.length;i++) {
File src = files[i];
File target = new File(trash, src.getName());
if (!src.renameTo(target)) {
success = false;
}
}
return success;
if (!trash.exists()) {
throw new IOException("The Trash was not found in its expected location (" + trash + ")");
}
List failed = new ArrayList();
for (int i=0;i < files.length;i++) {
File src = files[i];
File target = new File(trash, src.getName());
if (!src.renameTo(target)) {
failed.add(src);
}
}
if (failed.size() > 0) {
throw new IOException("The following files could not be trashed: " + failed);
}
return false;
}
}
@@ -105,6 +116,9 @@ public abstract class FileUtils {
trash = new File(desktop, ".Trash");
if (!trash.exists()) {
trash = new File(desktop, "Trash");
if (!trash.exists()) {
trash = new File(System.getProperty("fileutils.trash", "Trash"));
}
}
}
}
@@ -119,19 +133,22 @@ public abstract class FileUtils {
/** The default implementation attempts to move the file to
* the desktop "Trash" folder.
*/
public boolean moveToTrash(File[] files) {
public void moveToTrash(File[] files) throws IOException {
File trash = getTrashDirectory();
if (trash.exists()) {
boolean success = true;
for (int i=0;i < files.length;i++) {
File src = files[i];
File target = new File(trash, src.getName());
if (!src.renameTo(target))
success = false;
}
return success;
if (!trash.exists()) {
throw new IOException("No trash location found (define fileutils.trash to be the path to the trash)");
}
List failed = new ArrayList();
for (int i=0;i < files.length;i++) {
File src = files[i];
File target = new File(trash, src.getName());
if (!src.renameTo(target)) {
failed.add(src);
}
}
if (failed.size() > 0) {
throw new IOException("The following files could not be trashed: " + failed);
}
return false;
}
}
}
@@ -1,14 +1,15 @@
/* Copyright (c) 2007 Olivier Chafik, All Rights Reserved
*
* Copyright (c) 2008 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.examples;
@@ -20,10 +21,16 @@ import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/**
* Methods that are useful to decompose a raster in ranges of contiguous unoccupied pixels.
* An occupied pixel has two possible meanings, depending on the raster :
* Methods that are useful to decompose a raster into a set of rectangles.
* An occupied pixel has two possible meanings, depending on the raster :
* <ul>
* <li>if the raster has an alpha layer, occupied means with alpha not null</li>
* <li>if the raster doesn't have any alpha layer, occupied means not completely black</li>
@@ -31,12 +38,18 @@ import java.awt.image.SinglePixelPackedSampleModel;
* @author Olivier Chafik
*/
public class RasterRangesUtils {
/// Masks used to isolate the current column in a set of 8 binary columns packed in a byte
/// Masks used to isolate the current column in a set of 8 binary columns packed in a byte
private static final int[] subColMasks = new int[] {
0x0080, 0x0040, 0x0020, 0x0010,
0x0008, 0x0004, 0x0002, 0x0001
};
private static final Comparator COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
return ((Rectangle)o1).x - ((Rectangle)o2).x;
}
};
/**
* Abstraction of a sink for ranges.
*/
@@ -45,13 +58,13 @@ public class RasterRangesUtils {
* Output a rectangular range.
* @param x x coordinate of the top-left corner of the range
* @param y y coordinate of the top-left corner of the range
* @param w witdh of the range
* @param w width of the range
* @param h height of the range
* @return true if the output succeeded, false otherwise
*/
public boolean outputRange(int x, int y, int w, int h);
boolean outputRange(int x, int y, int w, int h);
}
/**
* Outputs ranges of occupied pixels.
* In a raster that has an alpha layer, a pixel is occupied if its alpha value is not null.
@@ -64,15 +77,15 @@ public class RasterRangesUtils {
Rectangle bounds = raster.getBounds();
SampleModel sampleModel = raster.getSampleModel();
boolean hasAlpha = sampleModel.getNumBands() == 4;
// Try to use the underlying data array directly for a few common raster formats
if (raster.getParent() == null && bounds.x == 0 && bounds.y == 0) {
// No support for subraster (as obtained with Image.getSubimage(...))
DataBuffer data = raster.getDataBuffer();
if (data.getNumBanks() == 1) {
// There is always a single bank for all BufferedImage types, except maybe TYPE_CUSTOM
if (sampleModel instanceof MultiPixelPackedSampleModel) {
MultiPixelPackedSampleModel packedSampleModel = (MultiPixelPackedSampleModel)sampleModel;
if (packedSampleModel.getPixelBitStride() == 1) {
@@ -93,18 +106,21 @@ public class RasterRangesUtils {
int[] pixels = raster.getPixels(0, 0, bounds.width, bounds.height, (int[])null);
return outputOccupiedRanges(pixels, bounds.width, bounds.height, hasAlpha ? 0xff000000 : 0xffffff, out);
}
/**
* Output the non-null values of a binary image as ranges of contiguous values.
* @param binaryBits byte-packed binary bits of an image
* @param w width of the image (in pixels)
* @param h height of the image
* @param output
* @param out
* @return true if the output succeeded, false otherwise
*/
public static boolean outputOccupiedRangesOfBinaryPixels(byte[] binaryBits, int w, int h, RangesOutput output) {
public static boolean outputOccupiedRangesOfBinaryPixels(byte[] binaryBits, int w, int h, RangesOutput out) {
Set rects = new HashSet();
Set prevLine = Collections.EMPTY_SET;
int scanlineBytes = binaryBits.length / h;
for (int row = 0; row < h; row++) {
Set curLine = new TreeSet(COMPARATOR);
int rowOffsetBytes = row * scanlineBytes;
int startCol = -1;
// Look at each batch of 8 columns in this row
@@ -115,9 +131,7 @@ public class RasterRangesUtils {
// all 8 bits are zeroes
if (startCol >= 0) {
// end of current region
if (!output.outputRange(startCol, row, firstByteCol - startCol, 1)) {
return false;
}
curLine.add(new Rectangle(startCol, row, firstByteCol - startCol, 1));
startCol = -1;
}
} else if (byteColBits == 0xff) {
@@ -138,9 +152,7 @@ public class RasterRangesUtils {
} else {
if (startCol >= 0) {
// end of current region
if (!output.outputRange(startCol, row, col - startCol, 1)) {
return false;
}
curLine.add(new Rectangle(startCol, row, col - startCol, 1));
startCol = -1;
}
}
@@ -149,15 +161,23 @@ public class RasterRangesUtils {
}
if (startCol >= 0) {
// end of last region
if (!output.outputRange(startCol, row, w - startCol, 1)) {
return false;
}
startCol = -1;
curLine.add(new Rectangle(startCol, row, w - startCol, 1));
}
Set unmerged = mergeRects(prevLine, curLine);
rects.addAll(unmerged);
prevLine = curLine;
}
// Add anything left over
rects.addAll(prevLine);
for (Iterator i=rects.iterator();i.hasNext();) {
Rectangle r = (Rectangle)i.next();
if (!out.outputRange(r.x, r.y, r.width, r.height)) {
return false;
}
}
return true;
}
/**
* Output the occupied values of an integer-pixels image as ranges of contiguous values.
* A pixel is considered occupied if the bitwise AND of its integer value with the provided occupationMask is not null.
@@ -169,11 +189,13 @@ public class RasterRangesUtils {
* @return true if the output succeeded, false otherwise
*/
public static boolean outputOccupiedRanges(int[] pixels, int w, int h, int occupationMask, RangesOutput out) {
Set rects = new HashSet();
Set prevLine = Collections.EMPTY_SET;
for (int row = 0; row < h; row++) {
Set curLine = new TreeSet(COMPARATOR);
int idxOffset = row * w;
int startCol = -1;
for (int col = 0; col < w; col++) {
if ((pixels[idxOffset + col] & occupationMask) != 0) {
if (startCol < 0) {
@@ -182,21 +204,55 @@ public class RasterRangesUtils {
} else {
if (startCol >= 0) {
// end of current region
if (!out.outputRange(startCol, row, col - startCol, 1)) {
return false;
}
curLine.add(new Rectangle(startCol, row, col-startCol, 1));
startCol = -1;
}
}
}
if (startCol >= 0) {
// end of last region of current row
if (!out.outputRange(startCol, row, w - startCol, 1)) {
return false;
}
startCol = -1;
curLine.add(new Rectangle(startCol, row, w-startCol, 1));
}
Set unmerged = mergeRects(prevLine, curLine);
rects.addAll(unmerged);
prevLine = curLine;
}
// Add anything left over
rects.addAll(prevLine);
for (Iterator i=rects.iterator();i.hasNext();) {
Rectangle r = (Rectangle)i.next();
if (!out.outputRange(r.x, r.y, r.width, r.height)) {
return false;
}
}
return true;
}
private static Set mergeRects(Set prev, Set current) {
Set unmerged = new HashSet(prev);
if (!prev.isEmpty() && !current.isEmpty()) {
Rectangle[] pr = (Rectangle[])prev.toArray(new Rectangle[prev.size()]);
Rectangle[] cr = (Rectangle[])current.toArray(new Rectangle[current.size()]);
int ipr = 0;
int icr = 0;
while (ipr < pr.length && icr < cr.length) {
while (cr[icr].x < pr[ipr].x) {
if (++icr == cr.length) {
return unmerged;
}
}
if (cr[icr].x == pr[ipr].x && cr[icr].width == pr[ipr].width) {
unmerged.remove(pr[ipr]);
cr[icr].y = pr[ipr].y;
cr[icr].height = pr[ipr].height + 1;
++icr;
}
else {
++ipr;
}
}
}
return unmerged;
}
}
@@ -239,8 +239,6 @@ public class ShapedWindowDemo {
frame.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
frame.getContentPane().add(face);
frame.setUndecorated(true);
frame.pack();
frame.setLocation(100, 100);
try {
Shape mask = new Area(new Ellipse2D.Float(0, 0, 150, 150));
WindowUtils.setWindowMask(frame, mask);
@@ -249,8 +247,11 @@ public class ShapedWindowDemo {
}
frame.setIconImage(face.getIconImage());
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(100, 100);
frame.setVisible(true);
}
catch(UnsatisfiedLinkError e) {
e.printStackTrace();
+273 -111
Ver Arquivo
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved
* Parts Copyright (c) 2007 Olivier Chafik
*
* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved
* Parts Copyright (c) 2007 Olivier Chafik
*
* 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;
@@ -16,6 +16,7 @@ package com.sun.jna.examples;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
@@ -29,6 +30,10 @@ import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import java.awt.AWTEvent;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
@@ -37,6 +42,7 @@ import java.awt.event.HierarchyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Area;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.util.ArrayList;
@@ -79,7 +85,7 @@ import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
/**
* Provides additional features on a Java {@link Window}.
* Provides additional features on a Java {@link Window}.
* <ul>
* <li>Non-rectangular shape (bitmap mask, no antialiasing)
* <li>Transparency (constant alpha applied to window contents or
@@ -106,7 +112,15 @@ import com.sun.jna.ptr.PointerByReference;
* Window#paint(Graphics)} on OS X, you'll need to explicitly set the clip
* mask on the <code>Graphics</code> object with the window mask; only the
* content pane of the window and below have the window mask automatically
* applied.
* applied.<p>
* NOTE: On OSX, the property
* <code>apple.awt.draggableWindowBackground</code> is set automatically when
* a window's background color has an alpha component. That property must be
* set to its final value <em>before</em> the heavyweight peer for the Window
* is created. Once {@link Component#addNotify} has been called on the
* component, causing creation of the heavyweight peer, changing this
* property has no effect.
* @see <a href="http://developer.apple.com/technotes/tn2007/tn2196.html#APPLE_AWT_DRAGGABLEWINDOWBACKGROUND">Apple Technote 2007</a>
*/
// TODO: setWindowMask() should accept a threshold; some cases want a
// 50% threshold, some might want zero/non-zero
@@ -135,7 +149,7 @@ public class WindowUtils {
* </pre></code>
*/
private static class HeavyweightForcer extends Window {
private boolean packed;
private final boolean packed;
public HeavyweightForcer(Window parent) {
super(parent);
@@ -161,8 +175,9 @@ public class WindowUtils {
*/
protected static class RepaintTrigger extends JComponent {
protected class Listener extends WindowAdapter implements
ComponentListener, HierarchyListener {
protected class Listener
extends WindowAdapter
implements ComponentListener, HierarchyListener, AWTEventListener {
public void windowOpened(WindowEvent e) {
repaint();
}
@@ -183,24 +198,35 @@ public class WindowUtils {
public void hierarchyChanged(HierarchyEvent e) {
repaint();
}
public void eventDispatched(AWTEvent e) {
Component src = (Component)e.getSource();
MouseEvent me = SwingUtilities.convertMouseEvent(src, (MouseEvent)e, content);
Component c = SwingUtilities.getDeepestComponentAt(content, me.getX(), me.getY());
if (c != null) {
setCursor(c.getCursor());
}
};
}
private Listener listener = createListener();
private JComponent content;
private final Listener listener = createListener();
private final JComponent content;
public RepaintTrigger(JComponent content) {
this.content = content;
}
public void addNotify() {
super.addNotify();
Window w = SwingUtilities.getWindowAncestor(this);
setSize(getParent().getSize());
w.addComponentListener(listener);
w.addWindowListener(listener);
Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.MOUSE_EVENT_MASK|AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
public void removeNotify() {
Toolkit.getDefaultToolkit().removeAWTEventListener(listener);
Window w = SwingUtilities.getWindowAncestor(this);
w.removeComponentListener(listener);
w.removeWindowListener(listener);
@@ -255,7 +281,7 @@ public class WindowUtils {
if (getWidth() > 0 && getHeight() > 0) {
final BufferedImage buf =
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g = buf.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, w, h);
@@ -278,10 +304,10 @@ public class WindowUtils {
*/
protected abstract void paintDirect(BufferedImage buf, Rectangle bounds);
}
protected Window getWindow(Component c) {
return c instanceof Window
? (Window)c : SwingUtilities.getWindowAncestor(c);
return c instanceof Window
? (Window)c : SwingUtilities.getWindowAncestor(c);
}
/**
* Execute the given action when the given window becomes
@@ -322,17 +348,16 @@ public class WindowUtils {
if (mask != MASK_NONE) {
Rectangle bounds = mask.getBounds();
if (bounds.width > 0 && bounds.height > 0) {
BufferedImage clip =
BufferedImage clip =
new BufferedImage(bounds.x + bounds.width,
bounds.y + bounds.height,
BufferedImage.TYPE_INT_ARGB);
BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g = clip.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.setColor(Color.black);
g.fillRect(0, 0, bounds.x + bounds.width, bounds.y + bounds.height);
g.setComposite(AlphaComposite.SrcOver);
g.setColor(Color.white);
g.fill(mask);
raster = clip.getAlphaRaster();
raster = clip.getRaster();
}
}
return raster;
@@ -366,7 +391,7 @@ public class WindowUtils {
});
return area;
}
/**
* Set the overall alpha transparency of the window. An alpha of
* 1.0 is fully opaque, 0.0 is fully transparent.
@@ -419,7 +444,7 @@ public class WindowUtils {
JRootPane root = rpc.getRootPane();
JLayeredPane lp = root.getLayeredPane();
Container c = root.getContentPane();
JComponent content =
JComponent content =
(c instanceof JComponent) ? (JComponent)c : null;
if (transparent) {
lp.putClientProperty(TRANSPARENT_OLD_OPAQUE,
@@ -454,7 +479,7 @@ public class WindowUtils {
protected void setMask(Component c, Raster raster) {
throw new UnsupportedOperationException("Window masking is not available");
}
/**
* Set the window mask based on the given Raster, which should
* be treated as a bitmap (zero/nonzero values only). A value of
@@ -591,7 +616,7 @@ public class WindowUtils {
int flags = user.GetWindowLong(hWnd, User32.GWL_EXSTYLE);
byte level = (byte)((int)(255 * alpha) & 0xFF);
if (usingUpdateLayeredWindow(w)) {
// If already using UpdateLayeredWindow, continue to
// If already using UpdateLayeredWindow, continue to
// do so
BLENDFUNCTION blend = new BLENDFUNCTION();
blend.SourceConstantAlpha = level;
@@ -715,9 +740,14 @@ public class WindowUtils {
ByteByReference bref = new ByteByReference();
IntByReference iref = new IntByReference();
byte level = getAlpha(win);
if (user.GetLayeredWindowAttributes(hWnd, null, bref, iref)
&& (iref.getValue() & User32.LWA_ALPHA) != 0) {
level = bref.getValue();
try {
// GetLayeredwindowAttributes supported WinXP and later
if (user.GetLayeredWindowAttributes(hWnd, null, bref, iref)
&& (iref.getValue() & User32.LWA_ALPHA) != 0) {
level = bref.getValue();
}
}
catch(UnsatisfiedLinkError e) {
}
blend.SourceConstantAlpha = level;
blend.AlphaFormat = User32.AC_SRC_ALPHA;
@@ -781,47 +811,103 @@ public class WindowUtils {
});
}
protected void setMask(final Component w, final Raster raster) {
public void setWindowMask(final Component w, final Shape mask) {
if (mask instanceof Area && ((Area)mask).isPolygonal()) {
setMask(w, (Area)mask);
}
else {
super.setWindowMask(w, mask);
}
}
// NOTE: Deletes hrgn after setting the window region
private void setWindowRegion(final Component w, final HRGN hrgn) {
whenDisplayable(w, new Runnable() {
public void run() {
GDI32 gdi = GDI32.INSTANCE;
User32 user = User32.INSTANCE;
HWND hWnd = getHWnd(w);
final HRGN result = gdi.CreateRectRgn(0, 0, 0, 0);
try {
if (raster == null) {
gdi.SetRectRgn(result, 0, 0, w.getWidth(), w.getHeight());
}
else {
final HRGN tempRgn = gdi.CreateRectRgn(0, 0, 0, 0);
try {
RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() {
public boolean outputRange(int x, int y, int w, int h) {
GDI32 gdi = GDI32.INSTANCE;
gdi.SetRectRgn(tempRgn, x, y, x + w, y + h);
return gdi.CombineRgn(result, result, tempRgn, GDI32.RGN_OR) != GDI32.ERROR;
}
});
}
finally {
gdi.DeleteObject(tempRgn);
}
}
user.SetWindowRgn(hWnd, result, true);
user.SetWindowRgn(hWnd, hrgn, true);
setForceHeavyweightPopups(getWindow(w), hrgn != null);
}
finally {
gdi.DeleteObject(result);
gdi.DeleteObject(hrgn);
}
setForceHeavyweightPopups(getWindow(w), raster != null);
}
});
}
// Take advantage of CreatePolyPolygonalRgn on w32
private void setMask(final Component w, final Area area) {
GDI32 gdi = GDI32.INSTANCE;
PathIterator pi = area.getPathIterator(null);
int mode = pi.getWindingRule() == PathIterator.WIND_NON_ZERO
? GDI32.WINDING: GDI32.ALTERNATE;
float[] coords = new float[6];
List points = new ArrayList();
int size = 0;
List sizes = new ArrayList();
while (!pi.isDone()) {
int type = pi.currentSegment(coords);
if (type == PathIterator.SEG_MOVETO) {
size = 1;
points.add(new POINT((int)coords[0], (int)coords[1]));
}
else if (type == PathIterator.SEG_LINETO) {
++size;
points.add(new POINT((int)coords[0], (int)coords[1]));
}
else if (type == PathIterator.SEG_CLOSE) {
sizes.add(new Integer(size));
}
else {
throw new RuntimeException("Area is not polygonal: " + area);
}
pi.next();
}
POINT[] lppt = (POINT[])new POINT().toArray(points.size());
POINT[] pts = (POINT[])points.toArray(new POINT[points.size()]);
for (int i=0;i < lppt.length;i++) {
lppt[i].x = pts[i].x;
lppt[i].y = pts[i].y;
}
int[] counts = new int[sizes.size()];
for (int i=0;i < counts.length;i++) {
counts[i] = ((Integer)sizes.get(i)).intValue();
}
HRGN hrgn = gdi.CreatePolyPolygonRgn(lppt, counts, counts.length, mode);
setWindowRegion(w, hrgn);
}
protected void setMask(final Component w, final Raster raster) {
GDI32 gdi = GDI32.INSTANCE;
final HRGN region = raster != null
? gdi.CreateRectRgn(0, 0, 0, 0) : null;
if (region != null) {
final HRGN tempRgn = gdi.CreateRectRgn(0, 0, 0, 0);
try {
RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() {
public boolean outputRange(int x, int y, int w, int h) {
GDI32 gdi = GDI32.INSTANCE;
gdi.SetRectRgn(tempRgn, x, y, x + w, y + h);
return gdi.CombineRgn(region, region, tempRgn, GDI32.RGN_OR) != GDI32.ERROR;
}
});
}
finally {
gdi.DeleteObject(tempRgn);
}
}
setWindowRegion(w, region);
}
}
private static class MacWindowUtils extends NativeWindowUtils {
public boolean isWindowAlphaSupported() {
return true;
}
private OSXTransparentContent installTransparentContent(Window w) {
OSXTransparentContent content;
if (w instanceof RootPaneContainer) {
@@ -850,32 +936,64 @@ public class WindowUtils {
return content;
}
/** Note that the property
* <code>apple.awt.draggableWindowBackground</code> must be set to its
* final value <em>before</em> the heavyweight peer for the Window is
* created. Once {@link Component#addNotify} has been called on the
* component, causing creation of the heavyweight peer, changing this
* property has no effect.
* @see <a href="http://developer.apple.com/technotes/tn2007/tn2196.html#APPLE_AWT_DRAGGABLEWINDOWBACKGROUND">Apple Technote 2007</a>
*/
public void setWindowTransparent(Window w, boolean transparent) {
boolean isTransparent = w.getBackground() != null
&& w.getBackground().getAlpha() == 0;
if (transparent != isTransparent) {
installTransparentContent(w);
setBackgroundTransparent(w, transparent);
setBackgroundTransparent(w, transparent, "setWindowTransparent");
setLayersTransparent(w, transparent);
}
}
/** Setting this false restores the original setting. */
private static final String WDRAG = "apple.awt.draggableWindowBackground";
private void fixWindowDragging(Window w, String context) {
if (w instanceof RootPaneContainer) {
JRootPane p = ((RootPaneContainer)w).getRootPane();
Boolean oldDraggable = (Boolean)p.getClientProperty(WDRAG);
if (oldDraggable == null) {
p.putClientProperty(WDRAG, Boolean.FALSE);
if (w.isDisplayable()) {
System.err.println(context + "(): To avoid content dragging, " + context + "() must be called before the window is realized, or " + WDRAG + " must be set to Boolean.FALSE before the window is realized. If you really want content dragging, set " + WDRAG + " on the window's root pane to Boolean.TRUE before calling " + context + "() to hide this message.");
}
}
}
}
/** Note that the property
* <code>apple.awt.draggableWindowBackground</code> must be set to its
* final value <em>before</em> the heavyweight peer for the Window is
* created. Once {@link Component#addNotify} has been called on the
* component, causing creation of the heavyweight peer, changing this
* property has no effect.
* @see <a href="http://developer.apple.com/technotes/tn2007/tn2196.html#APPLE_AWT_DRAGGABLEWINDOWBACKGROUND">Apple Technote 2007</a>
*/
public void setWindowAlpha(final Window w, final float alpha) {
if (w instanceof RootPaneContainer) {
JRootPane p = ((RootPaneContainer)w).getRootPane();
p.putClientProperty("Window.alpha", new Float(alpha));
fixWindowDragging(w, "setWindowAlpha");
}
whenDisplayable(w, new Runnable() {
public void run() {
Object peer = w.getPeer();
try {
peer.getClass().getMethod("setAlpha", new Class[]{
float.class
}).invoke(peer, new Object[]{
new Float(alpha)
});
float.class
}).invoke(peer, new Object[]{
new Float(alpha)
});
}
catch (Exception e) {
if (w instanceof RootPaneContainer) {
JRootPane p = ((RootPaneContainer)w).getRootPane();
p.putClientProperty("Window.alpha", new Float(alpha));
}
}
}
});
@@ -896,7 +1014,7 @@ public class WindowUtils {
Window w = (Window)c;
OSXTransparentContent content = installTransparentContent(w);
content.setMask(shape);
setBackgroundTransparent(w, shape != MASK_NONE);
setBackgroundTransparent(w, shape != MASK_NONE, "setWindowMask");
}
else {
// not yet implemented
@@ -915,7 +1033,7 @@ public class WindowUtils {
add(oldContent, BorderLayout.CENTER);
}
}
public void setMask(Shape shape) {
this.shape = shape;
repaint();
@@ -937,21 +1055,31 @@ public class WindowUtils {
}
}
}
private void setBackgroundTransparent(Window w, boolean transparent) {
private void setBackgroundTransparent(Window w, boolean transparent, String context) {
JRootPane rp = w instanceof RootPaneContainer
? ((RootPaneContainer)w).getRootPane() : null;
if (transparent) {
if (rp != null) {
rp.putClientProperty("bg.old", w.getBackground());
}
w.setBackground(new Color(0,0,0,0));
}
else {
// FIXME restore background to original color
w.setBackground(null);
if (rp != null) {
w.setBackground((Color)rp.getClientProperty("bg.old"));
}
else {
w.setBackground(null);
}
}
fixWindowDragging(w, context);
}
}
private static class X11WindowUtils extends NativeWindowUtils {
private Pixmap createBitmap(final Display dpy,
X11.Window win,
Raster raster) {
private static Pixmap createBitmap(final Display dpy,
X11.Window win,
Raster raster) {
final X11 x11 = X11.INSTANCE;
Rectangle bounds = raster.getBounds();
int width = bounds.x + bounds.width;
@@ -963,19 +1091,34 @@ public class WindowUtils {
}
x11.XSetForeground(dpy, gc, new NativeLong(0));
x11.XFillRectangle(dpy, pm, gc, 0, 0, width, height);
final int UNMASKED = 1;
x11.XSetForeground(dpy, gc, new NativeLong(UNMASKED));
X11.XWindowAttributes atts = new X11.XWindowAttributes();
int status = x11.XGetWindowAttributes(dpy, win, atts);
if (status == 0) {
return null;
}
final List rlist = new ArrayList();
try {
RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() {
public boolean outputRange(int x, int y, int w, int h) {
return x11.XFillRectangle(dpy, pm, gc, x, y, w, h) != 0;
rlist.add(new Rectangle(x, y, w, h));
return true;
}
});
X11.XRectangle[] rects = (X11.XRectangle[])
new X11.XRectangle().toArray(rlist.size());
for (int i=0;i < rects.length;i++) {
Rectangle r = (Rectangle)rlist.get(i);
rects[i].x = (short)r.x;
rects[i].y = (short)r.y;
rects[i].width = (short)r.width;
rects[i].height = (short)r.height;
// Optimization: write directly to native memory
Pointer p = rects[i].getPointer();
p.setShort(0, (short)r.x);
p.setShort(2, (short)r.y);
p.setShort(4, (short)r.width);
p.setShort(6, (short)r.height);
rects[i].setAutoSynch(false);
// End optimization
}
final int UNMASKED = 1;
x11.XSetForeground(dpy, gc, new NativeLong(UNMASKED));
x11.XFillRectangles(dpy, pm, gc, rects, rects.length);
}
finally {
x11.XFreeGC(dpy, gc);
@@ -990,7 +1133,7 @@ public class WindowUtils {
return getAlphaVisualIDs().length > 0;
}
private long getVisualID(GraphicsConfiguration config) {
private static long getVisualID(GraphicsConfiguration config) {
// Use reflection to call
// X11GraphicsConfig.getVisual
try {
@@ -1048,17 +1191,17 @@ public class WindowUtils {
template.screen = screen;
template.depth = 32;
template.c_class = X11.TrueColor;
NativeLong mask = new NativeLong(X11.VisualScreenMask
NativeLong mask = new NativeLong(X11.VisualScreenMask
| X11.VisualDepthMask
| X11.VisualClassMask);
IntByReference pcount = new IntByReference();
info = x11.XGetVisualInfo(dpy, mask, template, pcount);
if (info != null) {
List list = new ArrayList();
XVisualInfo[] infos =
XVisualInfo[] infos =
(XVisualInfo[])info.toArray(pcount.getValue());
for (int i = 0; i < infos.length; i++) {
XRenderPictFormat format =
XRenderPictFormat format =
X11.Xrender.INSTANCE.XRenderFindVisualFormat(dpy,
infos[i].visual);
if (format.type == X11.Xrender.PictTypeDirect
@@ -1082,8 +1225,8 @@ public class WindowUtils {
return alphaVisualIDs;
}
private X11.Window getContentWindow(Window w, X11.Display dpy,
X11.Window win, Point offset) {
private static X11.Window getContentWindow(Window w, X11.Display dpy,
X11.Window win, Point offset) {
if ((w instanceof Frame && !((Frame)w).isUndecorated())
|| (w instanceof Dialog && !((Dialog)w).isUndecorated())) {
X11 x11 = X11.INSTANCE;
@@ -1101,7 +1244,7 @@ public class WindowUtils {
x11.XGetWindowAttributes(dpy, child, xwa);
offset.x = -xwa.x;
offset.y = -xwa.y;
win = child;
win = child;
break;
}
if (p != null) {
@@ -1111,7 +1254,7 @@ public class WindowUtils {
return win;
}
private X11.Window getDrawable(Component w) {
private static X11.Window getDrawable(Component w) {
int id = (int)Native.getComponentID(w);
if (id == X11.None)
return null;
@@ -1158,15 +1301,15 @@ public class WindowUtils {
}
private class X11TransparentContent extends TransparentContent {
public X11TransparentContent(Container oldContent) {
super(oldContent);
}
private Memory buffer;
private int[] pixels;
private int[] pixel = new int[4];
// Painting directly to the original Graphics
private final int[] pixel = new int[4];
// Painting directly to the original Graphics
// fails to properly composite unless the destination
// is pure black. Too bad.
protected void paintDirect(BufferedImage buf, Rectangle bounds) {
@@ -1177,7 +1320,7 @@ public class WindowUtils {
Point offset = new Point();
win = getContentWindow(window, dpy, win, offset);
X11.GC gc = x11.XCreateGC(dpy, win, new NativeLong(0), null);
Raster raster = buf.getData();
int w = bounds.width;
int h = bounds.height;
@@ -1206,13 +1349,13 @@ public class WindowUtils {
offset.x += bounds.x;
offset.y += bounds.y;
x11.XPutImage(dpy, win, gc, image, 0, 0, offset.x, offset.y, w, h);
x11.XFree(image.getPointer());
x11.XFreeGC(dpy, gc);
x11.XCloseDisplay(dpy);
}
}
public void setWindowTransparent(final Window w,
final boolean transparent) {
if (!(w instanceof RootPaneContainer)) {
@@ -1251,29 +1394,26 @@ public class WindowUtils {
});
}
protected void setMask(final Component w, final Raster raster) {
private interface PixmapSource {
Pixmap getPixmap(Display dpy, X11.Window win);
}
private void setWindowShape(final Window w, final PixmapSource src) {
Runnable action = new Runnable() {
public void run() {
X11 x11 = X11.INSTANCE;
Xext ext = Xext.INSTANCE;
Display dpy = x11.XOpenDisplay(null);
if (dpy == null)
if (dpy == null) {
return;
}
Pixmap pm = null;
try {
X11.Window win = getDrawable(w);
if (raster == null
|| ((pm = createBitmap(dpy, win, raster)) == null)) {
ext.XShapeCombineMask(dpy, win,
X11.Xext.ShapeBounding,
0, 0, Pixmap.None,
X11.Xext.ShapeSet);
}
else {
ext.XShapeCombineMask(dpy, win,
X11.Xext.ShapeBounding, 0, 0,
pm, X11.Xext.ShapeSet);
}
pm = src.getPixmap(dpy, win);
Xext ext = Xext.INSTANCE;
ext.XShapeCombineMask(dpy, win, X11.Xext.ShapeBounding,
0, 0, pm == null ? Pixmap.None : pm,
X11.Xext.ShapeSet);
}
finally {
if (pm != null) {
@@ -1281,11 +1421,19 @@ public class WindowUtils {
}
x11.XCloseDisplay(dpy);
}
setForceHeavyweightPopups(getWindow(w), raster != null);
setForceHeavyweightPopups(getWindow(w), pm != null);
}
};
whenDisplayable(w, action);
}
protected void setMask(final Component w, final Raster raster) {
setWindowShape(getWindow(w), new PixmapSource() {
public Pixmap getPixmap(Display dpy, X11.Window win) {
return raster != null ? createBitmap(dpy, win, raster) : null;
}
});
}
}
/**
@@ -1298,7 +1446,7 @@ public class WindowUtils {
}
/**
* Applies the given mask to the given heavyweight component. Does nothing
* Applies the given mask to the given heavyweight component. Does nothing
* if the operation is not supported. The mask is treated as a bitmap and
* ignores transparency.
*/
@@ -1333,7 +1481,14 @@ public class WindowUtils {
* opaque, 0.0 fully transparent. The alpha level is applied equally
* to all window pixels.<p>
* NOTE: Windows requires that <code>sun.java2d.noddraw=true</code>
* in order for alpha to work.
* in order for alpha to work.<p>
* NOTE: On OSX, the property
* <code>apple.awt.draggableWindowBackground</code> must be set to its
* final value <em>before</em> the heavyweight peer for the Window is
* created. Once {@link Component#addNotify} has been called on the
* component, causing creation of the heavyweight peer, changing this
* property has no effect.
* @see <a href="http://developer.apple.com/technotes/tn2007/tn2196.html#APPLE_AWT_DRAGGABLEWINDOWBACKGROUND">Apple Technote 2007</a>
*/
public static void setWindowAlpha(Window w, float alpha) {
getInstance().setWindowAlpha(w, Math.max(0f, Math.min(alpha, 1f)));
@@ -1343,8 +1498,15 @@ public class WindowUtils {
* Set the window to be transparent. Only explicitly painted pixels
* will be non-transparent. All pixels will be composited with
* whatever is under the window using their alpha values.
*
* On OSX, the property <code>apple.awt.draggableWindowBackground</code>
* must be set to its final value <em>before</em> the heavyweight peer for
* the Window is created. Once {@link Component#addNotify} has been
* called on the component, causing creation of the heavyweight peer,
* changing this property has no effect.
* @see <a href="http://developer.apple.com/technotes/tn2007/tn2196.html#APPLE_AWT_DRAGGABLEWINDOWBACKGROUND">Apple Technote 2007</a>
*/
public static void setWindowTransparent(Window w, boolean transparent) {
getInstance().setWindowTransparent(w, transparent);
}
}
}
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+23 -19
Ver Arquivo
@@ -8,7 +8,7 @@
* 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.examples.win32;
@@ -17,15 +17,16 @@ import java.awt.Rectangle;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.User32.POINT;
import com.sun.jna.ptr.PointerByReference;
/** Definition (incomplete) of <code>gdi32.dll</code>. */
public interface GDI32 extends W32API {
GDI32 INSTANCE = (GDI32)
Native.loadLibrary("gdi32", GDI32.class, DEFAULT_OPTIONS);
public static class RECT extends Structure {
class RECT extends Structure {
public int left;
public int top;
public int right;
@@ -39,14 +40,14 @@ public interface GDI32 extends W32API {
}
int RDH_RECTANGLES = 1;
public static class RGNDATAHEADER extends Structure {
class RGNDATAHEADER extends Structure {
public int dwSize = size();
public int iType = RDH_RECTANGLES; // required
public int nCount;
public int nRgnSize;
public RECT rcBound;
public RECT rcBound;
}
public static class RGNDATA extends Structure {
class RGNDATA extends Structure {
public RGNDATAHEADER rdh;
public byte[] Buffer;
public RGNDATA(int bufferSize) {
@@ -54,7 +55,7 @@ public interface GDI32 extends W32API {
allocateMemory();
}
}
public HRGN ExtCreateRegion(Pointer lpXform, int nCount, RGNDATA lpRgnData);
int RGN_AND = 1;
@@ -62,35 +63,38 @@ public interface GDI32 extends W32API {
int RGN_XOR = 3;
int RGN_DIFF = 4;
int RGN_COPY = 5;
int ERROR = 0;
int NULLREGION = 1;
int SIMPLEREGION = 2;
int COMPLEXREGION = 3;
int CombineRgn(HRGN hrgnDest, HRGN hrgnSrc1, HRGN hrgnSrc2, int fnCombineMode);
HRGN CreateRectRgn(int nLeftRect, int nTopRect,
int nRightRect, int nBottomRect);
HRGN CreateRoundRectRgn(int nLeftRect, int nTopRect,
int nRightRect, int nBottomRect,
int nWidthEllipse,
int nWidthEllipse,
int nHeightEllipse);
int ALTERNATE = 1;
int WINDING = 2;
HRGN CreatePolyPolygonRgn(POINT[] lppt, int[] lpPolyCounts, int nCount, int fnPolyFillMode);
boolean SetRectRgn(HRGN hrgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
int SetPixel(HDC hDC, int x, int y, int crColor);
HDC CreateCompatibleDC(HDC hDC);
boolean DeleteDC(HDC hDC);
int BI_RGB = 0;
int BI_RLE8 = 1;
int BI_RLE4 = 2;
int BI_BITFIELDS = 3;
int BI_JPEG = 4;
int BI_PNG = 5;
public static class BITMAPINFOHEADER extends Structure {
class BITMAPINFOHEADER extends Structure {
public int biSize = size();
public int biWidth;
public int biHeight;
@@ -103,13 +107,13 @@ public interface GDI32 extends W32API {
public int biClrUsed;
public int biClrImportant;
}
public static class RGBQUAD extends Structure {
class RGBQUAD extends Structure {
public byte rgbBlue;
public byte rgbGreen;
public byte rgbRed;
public byte rgbReserved = 0;
}
public static class BITMAPINFO extends Structure {
class BITMAPINFO extends Structure {
public BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER();
//RGBQUAD:
//byte rgbBlue;
@@ -131,7 +135,7 @@ public interface GDI32 extends W32API {
PointerByReference ppvBits, Pointer hSection,
int dwOffset);
HBITMAP CreateCompatibleBitmap(HDC hDC, int width, int height);
HANDLE SelectObject(HDC hDC, HANDLE hGDIObj);
boolean DeleteObject(HANDLE p);
}
@@ -13,11 +13,8 @@
package com.sun.jna.examples.win32;
import java.nio.Buffer;
import com.sun.jna.FromNativeContext;
import com.sun.jna.Native;
import com.sun.jna.NativeMapped;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.Structure;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.ptr.IntByReference;
@@ -29,7 +26,7 @@ public interface Kernel32 extends W32API {
Kernel32 INSTANCE = (Kernel32)
Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
public static class SYSTEMTIME extends Structure {
class SYSTEMTIME extends Structure {
public short wYear;
public short wMonth;
public short wDayOfWeek;
@@ -50,8 +47,10 @@ public interface Kernel32 extends W32API {
int GetCurrentProcessId();
HANDLE GetCurrentProcess();
int GetProcessId(HANDLE process);
int GetProcessVersion(int processId);
int GetLastError();
void SetLastError(int dwErrCode);
int GetDriveType(String rootPathName);
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100;
int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
@@ -100,9 +99,17 @@ public interface Kernel32 extends W32API {
int FILE_ATTRIBUTE_OFFLINE = 0x00001000;
int FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
int FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
int DRIVE_UNKNOWN = 0;
int DRIVE_NO_ROOT_DIR = 1;
int DRIVE_REMOVABLE = 2;
int DRIVE_FIXED = 3;
int DRIVE_REMOTE = 4;
int DRIVE_CDROM = 5;
int DRIVE_RAMDISK = 6;
int GENERIC_WRITE = 0x40000000;
public static class SECURITY_ATTRIBUTES extends Structure {
class SECURITY_ATTRIBUTES extends Structure {
public int nLength = size();
public Pointer lpSecurityDescriptor;
public boolean bInheritHandle;
@@ -161,7 +168,7 @@ public interface Kernel32 extends W32API {
* into a large block of result memory rather than something that stands
* alone or is used for input.
*/
public static class FILE_NOTIFY_INFORMATION extends Structure {
class FILE_NOTIFY_INFORMATION extends Structure {
public int NextEntryOffset;
public int Action;
public int FileNameLength;
@@ -197,7 +204,7 @@ public interface Kernel32 extends W32API {
return next;
}
}
public static class OVERLAPPED extends Structure {
class OVERLAPPED extends Structure {
public int Internal;
public int InternalHigh;
public int Offset;
@@ -205,7 +212,7 @@ public interface Kernel32 extends W32API {
public Pointer hEvent;
}
// TODO: figure out how OVERLAPPED is used and apply an appropriate mapping
public static interface OVERLAPPED_COMPLETION_ROUTINE extends StdCallCallback {
interface OVERLAPPED_COMPLETION_ROUTINE extends StdCallCallback {
void callback(int errorCode, int nBytesTransferred, OVERLAPPED overlapped);
}
/** NOTE: only exists in unicode form (W suffix). Define this method
@@ -220,4 +227,14 @@ public interface Kernel32 extends W32API {
OVERLAPPED overlapped,
OVERLAPPED_COMPLETION_ROUTINE completionRoutine);
/** ASCII version. Use {@link Native#toString(byte[])} to obtain the short
* path from the <code>byte</code> array.
* Use only if <code>w32.ascii==true</code>.
*/
int GetShortPathName(String lpszLongPath, byte[] lpdzShortPath, int cchBuffer);
/** Unicode version (the default). Use {@link Native#toString(char[])} to
* obtain the short path from the <code>char</code> array.
*/
int GetShortPathName(String lpszLongPath, char[] lpdzShortPath, int cchBuffer);
}
@@ -45,7 +45,7 @@ public interface Shell32 extends W32API {
int FOF_NOERRORUI = 1024;
int FOF_NOCOPYSECURITYATTRIBS = 2048;
public static class SHFILEOPSTRUCT extends Structure {
class SHFILEOPSTRUCT extends Structure {
public HANDLE hwnd;
public int wFunc;
public String pFrom;
+39 -38
Ver Arquivo
@@ -8,14 +8,11 @@
* 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.examples.win32;
import com.sun.jna.FromNativeContext;
import com.sun.jna.IntegerType;
import com.sun.jna.Native;
import com.sun.jna.NativeMapped;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.GDI32.RECT;
@@ -24,7 +21,7 @@ import com.sun.jna.ptr.IntByReference;
/** Provides access to the w32 user32 library.
* Incomplete implementation to support demos.
*
*
* @author Todd Fast, todd.fast@sun.com
* @author twall@users.sf.net
*/
@@ -32,7 +29,7 @@ public interface User32 extends W32API {
User32 INSTANCE = (User32)
Native.loadLibrary("user32", User32.class, DEFAULT_OPTIONS);
HDC GetDC(HWND hWnd);
int ReleaseDC(HWND hWnd, HDC hDC);
@@ -42,8 +39,8 @@ public interface User32 extends W32API {
int FLASHW_ALL = (FLASHW_CAPTION|FLASHW_TRAY);
int FLASHW_TIMER = 4;
int FLASHW_TIMERNOFG = 12;
public static class FLASHWINFO extends Structure {
class FLASHWINFO extends Structure {
public int cbSize;
public HANDLE hWnd;
public int dwFlags;
@@ -72,20 +69,20 @@ public interface User32 extends W32API {
HWND FindWindow(String winClass, String title);
int GetClassName(HWND hWnd, byte[] lpClassName, int nMaxCount);
public static class GUITHREADINFO extends Structure {
class GUITHREADINFO extends Structure {
public int cbSize = size();
public int flags;
HWND hwndActive;
HWND hwndFocus;
HWND hwndCapture;
HWND hwndMenuOwner;
HWND hwndMoveSize;
HWND hwndCaret;
RECT rcCaret;
public HWND hwndActive;
public HWND hwndFocus;
public HWND hwndCapture;
public HWND hwndMenuOwner;
public HWND hwndMoveSize;
public HWND hwndCaret;
public RECT rcCaret;
}
boolean GetGUIThreadInfo(int idThread, GUITHREADINFO lpgui);
public static class WINDOWINFO extends Structure {
class WINDOWINFO extends Structure {
public int cbSize = size();
public RECT rcWindow;
public RECT rcClient;
@@ -114,12 +111,12 @@ public interface User32 extends W32API {
HICON LoadIcon(HINSTANCE hInstance, String iconName);
HANDLE LoadImage(HINSTANCE hinst, // handle to instance
String name, // image to load
int type, // image type
int xDesired, // desired width
int yDesired, // desired height
int load // load options
HANDLE LoadImage(HINSTANCE hinst, // handle to instance
String name, // image to load
int type, // image type
int xDesired, // desired width
int yDesired, // desired height
int load // load options
);
boolean DestroyIcon(HICON hicon);
@@ -140,7 +137,7 @@ public interface User32 extends W32API {
int SetWindowLong(HWND hWnd, int nIndex, int dwNewLong);
// Do not use this version on win64
Pointer SetWindowLong(HWND hWnd, int nIndex, Pointer dwNewLong);
LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);
LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLongPtr);
Pointer SetWindowLongPtr(HWND hWnd, int nIndex, Pointer dwNewLongPtr);
@@ -150,7 +147,7 @@ public interface User32 extends W32API {
int ULW_COLORKEY = 1;
int ULW_ALPHA = 2;
int ULW_OPAQUE = 4;
boolean SetLayeredWindowAttributes(HWND hwnd, int crKey,
boolean SetLayeredWindowAttributes(HWND hwnd, int crKey,
byte bAlpha, int dwFlags);
boolean GetLayeredWindowAttributes(HWND hwnd,
IntByReference pcrKey,
@@ -158,26 +155,30 @@ public interface User32 extends W32API {
IntByReference pdwFlags);
/** Defines the x- and y-coordinates of a point. */
public static class POINT extends Structure {
class POINT extends Structure {
public int x, y;
public POINT() { }
public POINT(int x, int y) { this.x = x; this.y = y; }
}
/** Specifies the width and height of a rectangle. */
public static class SIZE extends Structure {
class SIZE extends Structure {
public int cx, cy;
public SIZE() { }
public SIZE(int w, int h) { this.cx = w; this.cy = h; }
}
int AC_SRC_OVER = 0x00;
int AC_SRC_ALPHA = 0x01;
int AC_SRC_NO_PREMULT_ALPHA = 0x01;
int AC_SRC_NO_ALPHA = 0x02;
public static class BLENDFUNCTION extends Structure {
class BLENDFUNCTION extends Structure {
public byte BlendOp = AC_SRC_OVER; // only valid value
public byte BlendFlags = 0; // only valid value
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
boolean UpdateLayeredWindow(HWND hwnd, HDC hdcDst,
POINT pptDst, SIZE psize,
HDC hdcSrc, POINT pptSrc, int crKey,
boolean UpdateLayeredWindow(HWND hwnd, HDC hdcDst,
POINT pptDst, SIZE psize,
HDC hdcSrc, POINT pptSrc, int crKey,
BLENDFUNCTION pblend, int dwFlags);
int SetWindowRgn(HWND hWnd, HRGN hRgn, boolean bRedraw);
int VK_SHIFT = 16;
@@ -196,28 +197,28 @@ public interface User32 extends W32API {
int WH_MOUSE = 7;
int WH_KEYBOARD_LL = 13;
int WH_MOUSE_LL = 14;
public static class HHOOK extends HANDLE { }
public static interface HOOKPROC extends StdCallCallback { }
class HHOOK extends HANDLE { }
interface HOOKPROC extends StdCallCallback { }
int WM_KEYDOWN = 256;
int WM_KEYUP = 257;
int WM_SYSKEYDOWN = 260;
int WM_SYSKEYUP = 261;
public static class KBDLLHOOKSTRUCT extends Structure {
class KBDLLHOOKSTRUCT extends Structure {
public int vkCode;
public int scanCode;
public int flags;
public int time;
public ULONG_PTR dwExtraInfo;
}
public static interface LowLevelKeyboardProc extends HOOKPROC {
interface LowLevelKeyboardProc extends HOOKPROC {
LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam);
}
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, int dwThreadId);
LRESULT CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, Pointer lParam);
boolean UnhookWindowsHookEx(HHOOK hhk);
public static class MSG extends Structure {
class MSG extends Structure {
public HWND hWnd;
public int message;
public WPARAM wParam;
+27 -17
Ver Arquivo
@@ -46,7 +46,7 @@ public interface W32API extends StdCallLibrary, W32Errors {
};
Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
public static class HANDLE extends PointerType {
class HANDLE extends PointerType {
/** Override to the appropriate object for INVALID_HANDLE_VALUE. */
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
@@ -55,13 +55,23 @@ public interface W32API extends StdCallLibrary, W32Errors {
return o;
}
}
public static class HDC extends HANDLE { }
public static class HICON extends HANDLE { }
public static class HBITMAP extends HANDLE { }
public static class HRGN extends HANDLE { }
public static class HWND extends HANDLE { }
public static class HINSTANCE extends HANDLE { }
public static class HMODULE extends HINSTANCE { }
class WORD extends IntegerType {
public WORD() { this(0); }
public WORD(long value) { super(2, value); }
}
class DWORD extends IntegerType {
public DWORD() { this(0); }
public DWORD(long value) { super(4, value); }
}
class HDC extends HANDLE { }
class HICON extends HANDLE { }
class HBITMAP extends HANDLE { }
class HRGN extends HANDLE { }
class HWND extends HANDLE { }
class HINSTANCE extends HANDLE { }
class HMODULE extends HINSTANCE { }
/** Constant value representing an invalid HANDLE. */
HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
@@ -78,7 +88,7 @@ public interface W32API extends StdCallLibrary, W32Errors {
}
};
/** LPHANDLE */
public static class HANDLEByReference extends ByReference {
class HANDLEByReference extends ByReference {
public HANDLEByReference() {
this(null);
}
@@ -101,36 +111,36 @@ public interface W32API extends StdCallLibrary, W32Errors {
}
}
public static class LONG_PTR extends IntegerType {
class LONG_PTR extends IntegerType {
public LONG_PTR() { this(0); }
public LONG_PTR(long value) { super(Pointer.SIZE, value); }
}
public static class SSIZE_T extends LONG_PTR {
class SSIZE_T extends LONG_PTR {
public SSIZE_T() { this(0); }
public SSIZE_T(long value) { super(value); }
}
public static class ULONG_PTR extends IntegerType {
class ULONG_PTR extends IntegerType {
public ULONG_PTR() { this(0); }
public ULONG_PTR(long value) { super(Pointer.SIZE, value); }
}
public static class SIZE_T extends ULONG_PTR {
class SIZE_T extends ULONG_PTR {
public SIZE_T() { this(0); }
public SIZE_T(long value) { super(value); }
}
public static class LPARAM extends LONG_PTR {
class LPARAM extends LONG_PTR {
public LPARAM() { this(0); }
public LPARAM(long value) { super(value); }
}
public static class LRESULT extends LONG_PTR {
class LRESULT extends LONG_PTR {
public LRESULT() { this(0); }
public LRESULT(long value) { super(value); }
}
public static class UINT_PTR extends IntegerType {
class UINT_PTR extends IntegerType {
public UINT_PTR() { super(Pointer.SIZE); }
public UINT_PTR(long value) { super(Pointer.SIZE, value); }
public Pointer toPointer() { return Pointer.createConstant(longValue()); }
}
public static class WPARAM extends UINT_PTR {
class WPARAM extends UINT_PTR {
public WPARAM() { this(0); }
public WPARAM(long value) { super(value); }
}
+92 -21
Ver Arquivo
@@ -48,6 +48,7 @@ additional JNI or native code.
<li><a href="#invocation-mapping">Invocation Mapping</a>
<li><a href="#global-data">Library Global Data</a>
<li><a href="#crash-protection">VM Crash Protection</a>
<li><a href="#performance">Performance</a>
</ul>
<p>
@@ -65,13 +66,18 @@ public interface CLibrary extends Library {
The <code>String</code> passed to the <code>Native.loadLibrary</code> method
is the undecorated name of the shared library file. Here are some examples of
library name mappings.<p>
<center>
<table style="background-color: #EAEAEA;" width="400">
<style type="text/css">
table.styled { border-collapse:collapse; background-color:#EAEAEA; }
td { padding-left: 10px; padding-right: 10px; }
blockquote { background-color:#EAEAEA; }
</style>
<table border=1 borderColor=white class=styled>
<tr><td><b>OS</b></td><td><b>Library Name</b></td><td><b>String</b></td></tr>
<tr><td>Windows</td><td>user32.dll</td><td>user32</td></tr>
<tr><td>Linux</td><td>libX11.so</td><td>X11</td></tr>
<tr><td>Mac OS X</td><td>libm.dylib</td><td>m</td></tr>
</table></center>
<tr><td>Mac OS X Framework</td><td>/System/Library/Frameworks/Carbon.framework/Carbon</td><td>Carbon</td></tr>
</table>
<p>
Any given native library with a unique filesystem path is represented by a single instance of {@link com.sun.jna.NativeLibrary} and obtained via {@link com.sun.jna.NativeLibrary#getInstance(String)}. The native library will be unloaded when no longer referenced by any Java code.
<p>
@@ -99,7 +105,7 @@ An instance of the {@link com.sun.jna.Function} class is obtained through the {@
<h2>Marshalling/Unmarshalling (Java/Native Type Conversions)</h2>
Java types must be chosen to match native types of the same size. Following are the types supported by the JNA library.<p>
<center>
<table border=1 bordercolor=#CCCCCC style="border-collapse:collapse" width="100%">
<table border=1 borderColor=white class=styled width="100%">
<tr><td><b>Java Type</b></td><td><b>C Type</b></td><td><b>Native Representation</b></td></tr>
<tr><td>boolean</td><td>int</td><td>32-bit integer (customizable)</td>
<tr><td>byte</td><td>char</td><td>8-bit integer</td>
@@ -115,6 +121,8 @@ Java types must be chosen to match native types of the same size. Following are
<tr><td colspan=3>In addition to the above types, which are supported at the native layer, the JNA Java library automatically handles the following types. All but <code>NativeMapped</code> and <code>NativeLong</code> are converted to {@link com.sun.jna.Pointer} before being passed to the native layer.</td></tr>
<tr><td>{@link java.lang.String}</td><td>char*</td><td>NUL-terminated array (native encoding or <code>jna.encoding</code>)</td>
<tr><td>{@link com.sun.jna.WString}</td><td>wchar_t*</td><td>NUL-terminated array (unicode)</td>
<tr><td>{@link java.lang.String String[]}</td><td>char**</td><td>NULL-terminated array of C strings</td>
<tr><td>{@link com.sun.jna.WString WString[]}</td><td>wchar_t**</td><td>NULL-terminated array of wide C strings</td>
<tr><td>{@link com.sun.jna.Structure}</td><td>struct*<br>struct</td><td>pointer to struct (argument or return) ({@link com.sun.jna.Structure.ByReference or explicitly})<br>struct by value (member of struct) ({@link com.sun.jna.Structure.ByValue or explicitly})</td>
<tr><td>{@link com.sun.jna.Union}</td><td>union</td><td>same as <code>Structure</code></td>
<tr><td>{@link com.sun.jna.Structure Structure[]}</td><td>struct[]</td><td>array of structs, contiguous in memory</td>
@@ -129,10 +137,15 @@ Java types must be chosen to match native types of the same size. Following are
<ul>
<li>Unsigned values may be passed by assigning the corresponding
two's-complement representation to the signed type of the same size.
<li>Java arrays of primitive type may be wrapped by {@link java.nio.Buffer} in order to access a subset of the array (changing the effective size and/or offest).
<li>Java arrays of primitive type may be wrapped by {@link java.nio.Buffer} in
order to access a subset of the array (changing the effective size and/or
offest).
<li>Java arrays of primitive type are only valid for use within the scope of a
single call. If the native code keeps a reference to the memory, use {@link
com.sun.jna.Memory} or {@link java.nio.Buffer} instead.
<li>Primitive arrays and structures as members of a structure are overlaid on the parent structure memory.
<li>Bitfields must be manully packed into an integer type.
<li>All other types must eventually be converted to one of these basic types. Methods with arguments or return values of types other than these must either use types deriving from {@link com.sun.jna.NativeMapped} or supply type conversion information for the unsupported types.
<li>All other types must eventually be converted to one of the types in this table. Methods with arguments or return values of types other than these must either use types deriving from {@link com.sun.jna.NativeMapped} or supply type conversion information for the unsupported types.
<li>Type mapping behavior may be customized by providing a {@link com.sun.jna.TypeMapper} for the {@link com.sun.jna.Library#OPTION_TYPE_MAPPER} option when initializing a library interface. See {@link com.sun.jna.win32.W32APITypeMapper} for an example which provides custom conversion of boolean and String types. You are free to use whatever types are convenient in your defined interfaces, but all custom types <em>must</em> provide a mapping to one of the basic or derived types listed above.
<li>Type mapping may also be customized on a per-class basis for user-defined types by making the user-defined type implement the {@link com.sun.jna.NativeMapped} interface.
<li><code>Structure</code> and <code>Union</code> are <em>not</em> converted to <code>Pointer</code> when passed by value.
@@ -145,12 +158,14 @@ Java primitive arrays may be used wherever a native primitive array is used. An
To map a native multi-dimensional array, use a single-dimensional Java array with a number of elements equivalent to the full native array, e.g.<br>
<blockquote><code><pre>
// Original C code
int array[2][3];
#define DIM0 2
#define DIM1 3
int array[DIM0][DIM1];
int i,j;
for (i=0;i < 2;i++) {
for (j=0;j < 3;j++) {
array[i][j] = i*3 + j;
for (i=0;i < DIM0;i++) {
for (j=0;j < DIM1;j++) {
array[i][j] = i*DIM1 + j;
}
}
@@ -158,9 +173,9 @@ for (i=0;i < 2;i++) {
final int DIM0 = 2;
final int DIM1 = 3;
int[] array = new int[6];
for (int i=0;i < 2;i++) {
for (int j=0;j < 3;j++) {
array[i*3 + j] = i*3 + j;
for (int i=0;i < DIM0;i++) {
for (int j=0;j < DIM1;j++) {
array[i*DIM1 + j] = i*DIM1 + j;
}
}
</pre></code></blockquote>
@@ -196,6 +211,7 @@ the default platform encoding is used, unless the system property
<code>jna.encoding</code> is set to a valid encoding. This property may be
set to "UTF8", for example, to ensure all native strings use that encoding.
<p>
Arrays of <code>String</code> passed to native code (either as a function argument or callback return value) will be converted into a NULL-terminated array of <code>char*</code> (or <code>wchar_t*</code> in the case of an array of <code>WString</code>.
<a name="wide-strings"></a>
<h3>Wide Strings</h3>
@@ -222,8 +238,14 @@ JNA supports supplying Java callbacks to native code. You must define an
interface that extends the {@link com.sun.jna.Callback} interface, and define
a single <code>callback</code> method with a signature that matches the
function pointer required by the native code. The name of the method
<em>must</em> be "callback", and the arguments and return value follow the
same rules as for a direct function invocation.
may be something other than "callback" only if there is only a single method
in the interface which extends Callback or the class which implements
{@link com.sun.jna.Callback}. The arguments and return value follow the same rules
as for a
direct function invocation.
<p>
If the callback returns a <code>String</code> or <code>String[]</code>, the
returned memory will be valid until the returned object is GC'd.
<p>
If your native code initializes function pointers within a struct, JNA will
automatically generate an <code>Callback</code> instance matching the declared
@@ -239,10 +261,10 @@ struct _functions {
// Equivalent JNA mapping
public class Functions extends Structure {
public static interface OpenFunc extends Callback {
int callback(String name, int options);
int invoke(String name, int options);
}
public static interface CloseFunc extends Callback {
int callback(int fd);
int invoke(int fd);
}
public OpenFunc open;
public CloseFunc close;
@@ -250,8 +272,8 @@ public class Functions extends Structure {
...
Functions funcs = new Functions();
lib.init(funcs);
int fd = funcs.open.callback("myfile", 0);
funcs.close.callback(fd);
int fd = funcs.open.invoke("myfile", 0);
funcs.close.invoke(fd);
</pre></code></blockquote>
Callbacks may also be used as return values. Native function pointers are wrapped in a proxy implementing the declared Callback type, to facilitate calling from Java.
@@ -263,7 +285,7 @@ sig_t signal(int signal, sig_t sigfunc);
// Equivalent JNA mapping
public interface CLibrary extends Library {
public interface SignalFunction extends Callback {
void callback(int signal);
void invoke(int signal);
}
SignalFunction signal(int signal, SignalFunction func);
}
@@ -526,6 +548,37 @@ native memory, call {@link com.sun.jna.Structure#read()} (to update the entire
structure) or {@link com.sun.jna.Structure#readField(String)
data.readField("refCount")} (to update just the <code>refCount</code> field).
<h4>Read-only fields</h4>
If you want to absolutely prevent Java code from modifying
a <code>Structure</code>'s contents, you may mark its
fields <code>final</code>. Structure reads can still overwrite the values
based on native memory contents, but no Java code will be able to modify any
of the fields.
<blockquote><code><pre>
class ReadOnly extends com.sun.jna.Structure {
// Do not initialize the field here, or the compiler will inline the value!
public final int refCount;
{
// Initialize fields here, to ensure the values are not inlined
refCount = -1;
read();
// refCount might now have a different value
}
}
...
ReadOnly ro = new ReadOnly();
// Will not compile!
ro.refCount = 0;
</pre></code></blockquote>
Make certain you attend to the following:
<ol>
<li>All final fields should be initialized in the constructor.
<li>If you call Structure.read() from anywhere but the constructor, keep in
mind that the compiler and/or hotspot will be assuming field values will not
change across that function call.
</ol>
<a name="unions"></a>
<h3>Unions</h3>
Unions are a special type of Structure. Each declared field within the union
@@ -560,7 +613,25 @@ The method {@link com.sun.jna.NativeLibrary#getGlobalVariableAddress} may be use
<a href="#toc">Table of Contents</a>
<a name="crash-protection"></a>
<h2>VM Crash Protection</h2>
It is not uncommon when defining a new library and writing tests to encounter memory access errors which crash the VM. These are often caused by improper mappings or invalid arguments passed to the native library. To generate Java errors instead of crashing the VM, call {@link com.sun.jna.Native#setProtected Native.setProtected(true)}</code>.
It is not uncommon when defining a new library and writing tests to encounter memory access errors which crash the VM. These are often caused by improper mappings or invalid arguments passed to the native library. To generate Java errors instead of crashing the VM, call {@link com.sun.jna.Native#setProtected Native.setProtected(true)}</code>. Not all platforms support this protection; if not, the value of {@link com.sun.jna.Native#isProtected} will remain <code>false</code>.
<p>
<a href="#toc">Table of Contents</a>
<a name="performance"></a>
<h2>Performance</h2>
<h3>Pointer/Array/Buffer Variants</h3>
Java primitive arrays are generally slower to use than memory
(Pointer, Memory, or ByReference) or NIO buffers, since the Java memory has to
be pinned and possibly copied across the native call, since the Java array is not necessarily contiguously allocated.
<h3>Large Structures</h3>
Structures are normally written to native memory before and read back from
native memory after a function call. With very large structures, there can be
a performance hit using reflection to walk through all the fields. Structure
auto-synch can be disabled by calling
{@link com.sun.jna.Structure#setAutoSynch} with a <code>false</code> parameter.
It is then up to you to use {@link com.sun.jna.Structure#readField(String)}
and {@link com.sun.jna.Structure#writeField(String)}/{@link
com.sun.jna.Structure#writeField(String,Object)} to synch with just the fields
of interest.
</body>
</html>
@@ -61,11 +61,19 @@ public class StdCallFunctionMapper implements FunctionMapper {
pop += getArgumentNativeStackSize(argTypes[i]);
}
String decorated = name + "@" + pop;
int conv = StdCallLibrary.STDCALL_CONVENTION;
try {
name = library.getFunction(decorated, StdCallLibrary.STDCALL_CONVENTION).getName();
name = library.getFunction(decorated, conv).getName();
}
catch(UnsatisfiedLinkError e) {
// not found; let caller try undecorated version
// try with an explicit underscore
try {
name = library.getFunction("_" + decorated, conv).getName();
}
catch(UnsatisfiedLinkError e2) {
// not found; let caller try undecorated version
}
}
return name;
}
+28 -16
Ver Arquivo
@@ -274,6 +274,12 @@ public class ArgumentsMarshalTest extends TestCase {
assertEquals("Native address of structure should be returned",
struct.getPointer(),
lib.testStructurePointerArgument(struct));
// ensure that even if the argument is ByValue, it's passed as ptr
struct = new TestLibrary.CheckFieldAlignment.ByValue();
assertEquals("Structure argument should be passed according to method "
+ "parameter type, not argument type",
struct.getPointer(),
lib.testStructurePointerArgument(struct));
}
public void testStructureByValueArgument() {
@@ -334,11 +340,11 @@ public class ArgumentsMarshalTest extends TestCase {
}
public void testRejectNoncontiguousStructureArrayArgument() {
TestLibrary.CheckFieldAlignment[] block =
new TestLibrary.CheckFieldAlignment[] {
new TestLibrary.CheckFieldAlignment(),
new TestLibrary.CheckFieldAlignment(),
};
TestLibrary.CheckFieldAlignment s1, s2, s3;
s3 = new TestLibrary.CheckFieldAlignment();
s1 = new TestLibrary.CheckFieldAlignment();
s2 = new TestLibrary.CheckFieldAlignment();
TestLibrary.CheckFieldAlignment[] block = { s1, s2, s3 };
try {
lib.modifyStructureArray(block, block.length);
fail("Library invocation should fail");
@@ -350,7 +356,7 @@ public class ArgumentsMarshalTest extends TestCase {
public void testByteArrayArgument() {
byte[] buf = new byte[1024];
final byte MAGIC = (byte)0xED;
assertEquals("Wrong return value", buf.length, +
assertEquals("Wrong return value", buf.length,
lib.fillInt8Buffer(buf, buf.length, MAGIC));
for (int i=0;i < buf.length;i++) {
assertEquals("Bad value at index " + i, MAGIC, buf[i]);
@@ -360,7 +366,7 @@ public class ArgumentsMarshalTest extends TestCase {
public void testShortArrayArgument() {
short[] buf = new short[1024];
final short MAGIC = (short)0xABED;
assertEquals("Wrong return value", buf.length, +
assertEquals("Wrong return value", buf.length,
lib.fillInt16Buffer(buf, buf.length, MAGIC));
for (int i=0;i < buf.length;i++) {
assertEquals("Bad value at index " + i, MAGIC, buf[i]);
@@ -370,7 +376,7 @@ public class ArgumentsMarshalTest extends TestCase {
public void testIntArrayArgument() {
int[] buf = new int[1024];
final int MAGIC = 0xABEDCF23;
assertEquals("Wrong return value", buf.length, +
assertEquals("Wrong return value", buf.length,
lib.fillInt32Buffer(buf, buf.length, MAGIC));
for (int i=0;i < buf.length;i++) {
assertEquals("Bad value at index " + i, MAGIC, buf[i]);
@@ -380,7 +386,7 @@ public class ArgumentsMarshalTest extends TestCase {
public void testLongArrayArgument() {
long[] buf = new long[1024];
final long MAGIC = 0x1234567887654321L;
assertEquals("Wrong return value", buf.length, +
assertEquals("Wrong return value", buf.length,
lib.fillInt64Buffer(buf, buf.length, MAGIC));
for (int i=0;i < buf.length;i++) {
assertEquals("Bad value at index " + i, MAGIC, buf[i]);
@@ -483,21 +489,27 @@ public class ArgumentsMarshalTest extends TestCase {
}
public void testPointerArrayArgument() {
Pointer[] args = { new NativeString(getName()).getPointer(),
new NativeString(getName()+"2").getPointer() };
Pointer[] args = {
new NativeString(getName()).getPointer(),
null,
new NativeString(getName()+"2").getPointer(),
};
assertEquals("Wrong value returned", args[0], lib.returnPointerArrayElement(args, 0));
assertEquals("Wrong value returned", args[1], lib.returnPointerArrayElement(args, 1));
assertNull("Native array should be null terminated", lib.returnPointerArrayElement(args, 2));
assertNull("Wrong value returned", lib.returnPointerArrayElement(args, 1));
assertEquals("Wrong value returned", args[2], lib.returnPointerArrayElement(args, 2));
assertNull("Native array should be null terminated", lib.returnPointerArrayElement(args, 3));
}
public void testStructureByReferenceArrayArgument() {
CheckFieldAlignment.ByReference[] args = {
new CheckFieldAlignment.ByReference(),
new CheckFieldAlignment.ByReference()
null,
new CheckFieldAlignment.ByReference(),
};
assertEquals("Wrong value returned", args[0], lib.returnPointerArrayElement(args, 0));
assertEquals("Wrong value returned", args[1], lib.returnPointerArrayElement(args, 1));
assertNull("Native array should be null terminated", lib.returnPointerArrayElement(args, 2));
assertNull("Wrong value returned", lib.returnPointerArrayElement(args, 1));
assertEquals("Wrong value returned", args[2], lib.returnPointerArrayElement(args, 2));
assertNull("Native array should be null terminated", lib.returnPointerArrayElement(args, 3));
}
public void testModifiedCharArrayArgument() {
+160 -1
Ver Arquivo
@@ -1,4 +1,4 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
/* Copyright (c) 2007-2008 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,6 +12,7 @@
*/
package com.sun.jna;
import java.util.HashMap;
import java.util.Map;
import com.sun.jna.CallbacksTest.TestLibrary.CbCallback;
@@ -47,6 +48,14 @@ public class CallbacksTest extends TestCase {
void callback();
}
void callVoidCallback(VoidCallback c);
interface VoidCallbackCustom extends Callback {
void customMethodName();
}
abstract class VoidCallbackCustomAbstract implements VoidCallbackCustom {
public void customMethodName() { }
}
class VoidCallbackCustomDerived extends VoidCallbackCustomAbstract { }
void callVoidCallback(VoidCallbackCustom c);
interface BooleanCallback extends Callback {
boolean callback(boolean arg, boolean arg2);
}
@@ -94,12 +103,22 @@ public class CallbacksTest extends TestCase {
interface CopyArgToByReference extends Callback {
int callback(int arg, IntByReference result);
}
interface StringArrayCallback extends Callback {
String[] callback(String[] arg);
}
Pointer callStringArrayCallback(StringArrayCallback c, String[] arg);
int callCallbackWithByReferenceArgument(CopyArgToByReference cb, int arg, IntByReference result);
TestStructure.ByValue callCallbackWithStructByValue(TestStructure.TestCallback callback, TestStructure.ByValue cbstruct);
interface CbCallback extends Callback {
CbCallback callback(CbCallback arg);
}
CbCallback callCallbackWithCallback(CbCallback cb);
public interface Int32CallbackX extends Callback {
public int callback(int arg);
}
Int32CallbackX returnCallback();
Int32CallbackX returnCallbackArgument(Int32CallbackX cb);
}
TestLibrary lib;
@@ -146,6 +165,17 @@ public class CallbacksTest extends TestCase {
assertEquals("Callback trampoline not freed", 0, cbstruct.peer);
}
public void testFindCallbackInterface() {
TestLibrary.Int32Callback cb = new TestLibrary.Int32Callback() {
public int callback(int arg, int arg2) {
return arg + arg2;
}
};
assertEquals("Wrong callback interface",
TestLibrary.Int32Callback.class,
Native.findCallbackClass(cb.getClass()));
}
public void testCallInt32Callback() {
final int MAGIC = 0x11111111;
final boolean[] called = { false };
@@ -406,6 +436,24 @@ public class CallbacksTest extends TestCase {
assertEquals("Wrong wide string return", VALUE, value);
}
public void testCallStringArrayCallback() {
final boolean[] called = {false};
final String[][] cbargs = { null };
TestLibrary.StringArrayCallback cb = new TestLibrary.StringArrayCallback() {
public String[] callback(String[] arg) {
called[0] = true;
cbargs[0] = arg;
return arg;
}
};
final String[] VALUE = { "value", null };
Pointer value = lib.callStringArrayCallback(cb, VALUE);
assertTrue("Callback not called", called[0]);
assertEquals("Wrong callback argument 1", VALUE[0], cbargs[0][0]);
String[] result = value.getStringArray(0);
assertEquals("Wrong String return", VALUE[0], result[0]);
}
public void testCallCallbackWithByReferenceArgument() {
final boolean[] called = {false};
TestLibrary.CopyArgToByReference cb = new TestLibrary.CopyArgToByReference() {
@@ -427,6 +475,7 @@ public class CallbacksTest extends TestCase {
final TestStructure innerResult = new TestStructure();
TestStructure.TestCallback cb = new TestStructure.TestCallback() {
public TestStructure.ByValue callback(TestStructure.ByValue s) {
// Copy the argument value for later comparison
Pointer old = innerResult.getPointer();
innerResult.useMemory(s.getPointer());
innerResult.read();
@@ -456,6 +505,116 @@ public class CallbacksTest extends TestCase {
assertEquals("Callback reference should be reused", cb, cb2);
}
public static interface CallbackTestLibrary extends Library {
interface Int32Callback extends Callback {
float callback(float arg, float arg2);
}
float callInt32Callback(Int32Callback c, float arg, float arg2);
}
public void testCallbackTypeMappingFromLibrary() throws Exception {
final DefaultTypeMapper mapper = new DefaultTypeMapper();
Map options = new HashMap() {
{ put(Library.OPTION_TYPE_MAPPER, mapper); }
};
CallbackTestLibrary lib = (CallbackTestLibrary)
Native.loadLibrary("testlib", CallbackTestLibrary.class, options);
// Convert java floats into native integers and back
TypeConverter converter = new TypeConverter() {
public Object fromNative(Object value, FromNativeContext context) {
return new Float(((Integer)value).intValue());
}
public Class nativeType() {
return Integer.class;
}
public Object toNative(Object value, ToNativeContext ctx) {
return new Integer(Math.round(((Float)value).floatValue()));
}
};
mapper.addTypeConverter(float.class, converter);
CallbackTestLibrary.Int32Callback cb = new CallbackTestLibrary.Int32Callback() {
public float callback(float arg, float arg2) {
return arg + arg2;
}
};
assertEquals("Wrong type mapper for callback class", mapper,
Native.getTypeMapper(CallbackTestLibrary.Int32Callback.class));
assertEquals("Wrong type mapper for callback object", mapper,
Native.getTypeMapper(cb.getClass()));
assertEquals("Wrong type mapper used in callback invocation",
-2, lib.callInt32Callback(cb, -1, -1), 0);
}
private static class TestCallback implements Callback {
public static final TypeMapper TYPE_MAPPER = new DefaultTypeMapper();
public void callback() { }
}
public void testCallbackTypeMappingFromCallback() throws Exception {
assertEquals("Wrong type mapper for callback class",
TestCallback.TYPE_MAPPER,
Native.getTypeMapper(TestCallback.class));
}
public void testInvokeCallback() {
TestLibrary lib = (TestLibrary)
Native.loadLibrary("testlib", TestLibrary.class);
TestLibrary.Int32CallbackX cb = lib.returnCallback();
assertNotNull("Callback should not be null", cb);
assertEquals("Callback should be callable", 1, cb.callback(1));
TestLibrary.Int32CallbackX cb2 = new TestLibrary.Int32CallbackX() {
public int callback(int arg) {
return 0;
}
};
assertSame("Java callback should be looked up",
cb2, lib.returnCallbackArgument(cb2));
assertSame("Existing native function wrapper should be reused",
cb, lib.returnCallbackArgument(cb));
}
static class CbStruct extends Structure {
public Callback cb;
}
interface CbTest extends Library {
public void callCallbackInStruct(CbStruct cbstruct);
}
public void testCallCallbackInStructure() {
final boolean[] flag = {false};
final CbStruct s = new CbStruct();
s.cb = new Callback() {
public void callback() {
flag[0] = true;
}
};
CbTest lib = (CbTest)Native.loadLibrary("testlib", CbTest.class);
lib.callCallbackInStruct(s);
assertTrue("Callback not invoked", flag[0]);
}
public void testCustomCallbackMethodName() {
final boolean[] called = {false};
TestLibrary.VoidCallbackCustom cb = new TestLibrary.VoidCallbackCustom() {
public void customMethodName() {
called[0] = true;
}
public String toString() {
return "Some debug output";
}
};
lib.callVoidCallback(cb);
assertTrue("Callback with custom method name not called", called[0]);
}
public void testCustomCallbackVariedInheritance() {
final boolean[] called = {false};
TestLibrary.VoidCallbackCustom cb =
new TestLibrary.VoidCallbackCustomDerived();
lib.callVoidCallback(cb);
}
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(CallbacksTest.class);
}
+29 -6
Ver Arquivo
@@ -3,24 +3,41 @@ package com.sun.jna;
import junit.framework.TestCase;
public class IntegerTypeTest extends TestCase {
private class Sized extends IntegerType {
public static class Sized extends IntegerType {
public Sized() { this(4, 0); }
public Sized(int size, long value) { super(size, value); }
}
public void testWriteNull() {
class NTStruct extends Structure {
public Sized field;
}
NTStruct s = new NTStruct();
assertNotNull("Field not initialized", s.field);
}
public void testReadNull() {
class NTStruct extends Structure {
public Sized field;
}
NTStruct s = new NTStruct();
s.read();
assertNotNull("Integer type field should be initialized on read", s.field);
}
public void testCheckArgumentSize() {
for (int i=1;i <= 8;i*=2) {
long value = -1L << (i*8-1);
long value = -1L << (i*8-1);
new Sized(i, value);
new Sized(i, -1);
new Sized(i, 0);
new Sized(i, 1);
value = 1L << (i*8-1);
new Sized(i, value);
value = -1L & ~(-1L << (i*8));
new Sized(i, value);
if (i < 8) {
try {
value = 1L << (i*8);
@@ -42,6 +59,12 @@ public class IntegerTypeTest extends TestCase {
}
}
public void testInitialValue() {
long VALUE = 20;
NativeLong nl = new NativeLong(VALUE);
assertEquals("Wrong initial value", VALUE, nl.longValue());
}
public static void main(String[] args) {
junit.textui.TestRunner.run(IntegerTypeTest.class);
}
+5 -2
Ver Arquivo
@@ -17,15 +17,18 @@ import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Properties;
import junit.framework.TestCase;
public class JNAUnloadTest extends TestCase {
private static final String BUILDDIR =
System.getProperty("jna.builddir", "build"
+ (Native.POINTER_SIZE == 8 ? "-d64" : ""));
private static class TestLoader extends URLClassLoader {
public TestLoader() throws MalformedURLException {
super(new URL[] {
new File("build/classes").toURI().toURL(),
new File(BUILDDIR + "/classes").toURI().toURL(),
}, null);
}
}
+22 -5
Ver Arquivo
@@ -19,14 +19,15 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import javax.swing.JFrame;
import junit.framework.TestCase;
public class LibraryLoadTest extends TestCase {
private static final String BUILDDIR =
System.getProperty("jna.builddir", "build"
+ (Native.POINTER_SIZE == 8 ? "-d64" : ""));
public void testLoadJNALibrary() {
assertTrue("Point size should never be zero", Pointer.SIZE > 0);
}
@@ -83,11 +84,11 @@ public class LibraryLoadTest extends TestCase {
try { os.close(); } catch(IOException e) { }
}
}
public void testLoadLibraryWithUnicodeName() throws Exception {
String tmp = System.getProperty("java.io.tmpdir");
String libName = System.mapLibraryName("jnidispatch");
File src = new File("build/native", libName);
File src = new File(BUILDDIR + "/native", libName);
String newLibName = UNICODE;
if (libName.startsWith("lib"))
newLibName = "lib" + newLibName;
@@ -122,6 +123,22 @@ public class LibraryLoadTest extends TestCase {
}
}
public interface TestLib2 extends Library {
int dependentReturnFalse();
}
public void testLoadDependentLibrary() {
try {
TestLib2 lib = (TestLib2)Native.loadLibrary("testlib2", TestLib2.class);
lib.dependentReturnFalse();
}
catch(UnsatisfiedLinkError e) {
// failure expected on anything but windows
if (Platform.isWindows()) {
fail("Failed to load dependent libraries: " + e);
}
}
}
public static void main(String[] args) {
junit.textui.TestRunner.run(LibraryLoadTest.class);
}
+11 -2
Ver Arquivo
@@ -17,14 +17,23 @@ import junit.framework.TestCase;
public class MemoryTest extends TestCase {
public void testAutoFreeMemory() throws Exception {
Memory core = new Memory(10);
final boolean[] flag = { false };
Memory core = new Memory(10) {
protected void finalize() {
super.finalize();
flag[0] = true;
}
};
Pointer shared = core.share(0, 5);
WeakReference ref = new WeakReference(core);
core = null;
System.gc();
long start = System.currentTimeMillis();
assertNotNull("Memory prematurely GC'd", ref.get());
assertFalse("Memory prematurely GC'd", flag[0]);
// This check fails on IBM's J9, on which the weak ref
// is cleared but the object not yet GC'd
//assertNotNull("Memory prematurely GC'd", ref.get());
shared = null;
System.gc();
while (ref.get() != null) {
+42 -10
Ver Arquivo
@@ -135,19 +135,51 @@ public class NativeLibraryTest extends TestCase {
}
public void testMatchUnversionedToVersioned() throws Exception {
File lib0 = File.createTempFile("lib", ".so.1");
File lib0 = File.createTempFile("lib", ".so.0");
File dir = lib0.getParentFile();
String name = lib0.getName();
name = name.substring(3, name.indexOf(".so"));
lib0.deleteOnExit();
File lib1 = File.createTempFile("lib", ".so.2.0");
File lib1 = new File(dir, "lib" + name + ".so.1.0");
lib1.createNewFile();
lib1.deleteOnExit();
File lib = File.createTempFile("lib", ".so.2.1");
lib.deleteOnExit();
String name = lib.getName();
name = name.substring(3, name.length()-5);
File dir = lib.getParentFile();
File lib1_1 = new File(dir, "lib" + name + ".so.1.1");
lib1_1.createNewFile();
lib1_1.deleteOnExit();
List path = Arrays.asList(new String[] { dir.getAbsolutePath() });
assertEquals("Versioned library not found when unversioned requested",
lib.getAbsolutePath(),
NativeLibrary.matchLibrary(name, path));
assertEquals("Latest versioned library not found when unversioned requested",
lib1_1.getAbsolutePath(),
NativeLibrary.matchLibrary(name, path));
}
public void testAvoidFalseMatch() throws Exception {
File lib0 = File.createTempFile("lib", ".so.1");
File dir = lib0.getParentFile();
lib0.deleteOnExit();
String name = lib0.getName();
name = name.substring(3, name.indexOf(".so"));
File lib1 = new File(dir, "lib" + name + "-client.so.2");
lib1.createNewFile();
lib1.deleteOnExit();
List path = Arrays.asList(new String[] { dir.getAbsolutePath() });
assertEquals("Library with similar prefix should be ignored",
lib0.getAbsolutePath(),
NativeLibrary.matchLibrary(name, path));
}
public void testParseVersion() throws Exception {
String[] VERSIONS = {
"1",
"1.2",
"1.2.3",
"1.2.3.4",
};
double[] EXPECTED = {
1, 1.02, 1.0203, 1.020304,
};
for (int i=0;i < VERSIONS.length;i++) {
assertEquals("Badly parsed version", EXPECTED[i], NativeLibrary.parseVersion(VERSIONS[i]), 0.0000001);
}
}
public static void main(String[] args) {
+19 -8
Ver Arquivo
@@ -84,21 +84,32 @@ public class NativeTest extends TestCase {
}
public void testSynchronizedAccess() throws Exception {
final boolean[] lockHeld = { false };
TestLib base = (TestLib)Native.loadLibrary("testlib", TestLib.class);
final TestLib lib = (TestLib)Native.synchronizedLibrary(base);
final NativeLibrary nlib = NativeLibrary.getInstance("testlib");
final TestLib lib = (TestLib)Native.loadLibrary("testlib", TestLib.class);
final TestLib synchlib = (TestLib)Native.synchronizedLibrary(lib);
final TestLib.VoidCallback cb = new TestLib.VoidCallback() {
public void callback() {
lockHeld[0] = Thread.holdsLock(NativeLibrary.getInstance("testlib"));
lockHeld[0] = Thread.holdsLock(nlib);
}
};
Thread t1 = new Thread() {
Thread t0 = new Thread() {
public void run() {
lib.callVoidCallback(cb);
}
};
t0.start();
t0.join();
assertFalse("NativeLibrary lock should not be held during native call to normal library",
lockHeld[0]);
Thread t1 = new Thread() {
public void run() {
synchlib.callVoidCallback(cb);
}
};
t1.start();
t1.join();
assertTrue("NativeLibrary lock should be held during native call",
assertTrue("NativeLibrary lock should be held during native call to synchronized library",
lockHeld[0]);
}
@@ -115,11 +126,11 @@ public class NativeTest extends TestCase {
Class subClass = TestInterface.InnerTestClass.InnerSubclass.class;
Class callbackClass = TestInterface.InnerTestClass.TestCallback.class;
assertEquals("Enclosing interface not found for class",
interfaceClass, Native.findLibraryClass(cls));
interfaceClass, Native.findEnclosingLibraryClass(cls));
assertEquals("Enclosing interface not found for derived class",
interfaceClass, Native.findLibraryClass(subClass));
interfaceClass, Native.findEnclosingLibraryClass(subClass));
assertEquals("Enclosing interface not found for callback",
interfaceClass, Native.findLibraryClass(callbackClass));
interfaceClass, Native.findEnclosingLibraryClass(callbackClass));
}
public interface TestInterfaceWithInstance extends Library {
+34 -21
Ver Arquivo
@@ -67,11 +67,10 @@ public class ReturnTypesTest extends TestCase {
SimpleStructure returnStaticTestStructure();
SimpleStructure returnNullTestStructure();
TestStructure.ByValue returnStructureByValue();
public interface Int32Callback extends Callback {
public int callback(int arg);
}
Int32Callback returnCallback();
Int32Callback returnCallbackArgument(Int32Callback cb);
Pointer[] returnPointerArgument(Pointer[] arg);
String[] returnPointerArgument(String[] arg);
WString[] returnPointerArgument(WString[] arg);
}
TestLibrary lib;
@@ -194,22 +193,6 @@ public class ReturnTypesTest extends TestCase {
assertNull("Expect null structure return", s);
}
public void testInvokeCallback() {
TestLibrary.Int32Callback cb = lib.returnCallback();
assertNotNull("Callback should not be null", cb);
assertEquals("Callback should be callable", 1, cb.callback(1));
TestLibrary.Int32Callback cb2 = new TestLibrary.Int32Callback() {
public int callback(int arg) {
return 0;
}
};
assertSame("Java callback should be looked up",
cb2, lib.returnCallbackArgument(cb2));
assertSame("Existing native function wrapper should be reused",
cb, lib.returnCallbackArgument(cb));
}
public void testReturnStructureByValue() {
TestStructure s = lib.returnStructureByValue();
assertNotNull("Returned structure must not be null", s);
@@ -222,6 +205,36 @@ public class ReturnTypesTest extends TestCase {
assertEquals("Wrong inner structure value", 5, s.inner.value, 0);
}
public void testReturnPointerArray() {
Pointer value = new Memory(10);
Pointer[] input = {
value, null,
};
Pointer[] result = lib.returnPointerArgument(input);
assertEquals("Wrong array length", input.length-1, result.length);
assertEquals("Wrong array element value", value, result[0]);
}
public void testReturnStringArray() {
String value = getName();
String[] input = {
value, null,
};
String[] result = lib.returnPointerArgument(input);
assertEquals("Wrong array length", input.length-1, result.length);
assertEquals("Wrong array element value", value, result[0]);
}
public void testReturnWStringArray() {
WString value = new WString(getName());
WString[] input = {
value, null,
};
WString[] result = lib.returnPointerArgument(input);
assertEquals("Wrong array length", input.length-1, result.length);
assertEquals("Wrong array element value", value, result[0]);
}
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(ReturnTypesTest.class);
}
+107
Ver Arquivo
@@ -0,0 +1,107 @@
/* 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.
* <p/>
* 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.
*/
package com.sun.jna;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Map;
import junit.framework.TestCase;
/** General structure by value functionality tests. */
public class StructureByValueTest extends TestCase {
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(StructureByValueTest.class);
}
public static class TestNativeMappedInStructure extends Structure {
public static class ByValue extends TestNativeMappedInStructure implements Structure.ByValue { }
public NativeLong field;
}
public void testNativeMappedInByValue() {
new TestNativeMappedInStructure.ByValue();
}
public interface TestLibrary extends Library {
byte testStructureByValueArgument8(ByValue8 arg);
short testStructureByValueArgument16(ByValue16 arg);
int testStructureByValueArgument32(ByValue32 arg);
long testStructureByValueArgument64(ByValue64 arg);
long testStructureByValueArgument128(ByValue128 arg);
}
TestLibrary lib;
protected void setUp() {
lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class);
}
protected void tearDown() {
lib = null;
}
public static class ByValueStruct extends Structure implements Structure.ByValue { }
public static class ByValue8 extends ByValueStruct {
public byte data;
}
public static class ByValue16 extends ByValueStruct {
public short data;
}
public static class ByValue32 extends ByValueStruct {
public int data;
}
public static class ByValue64 extends ByValueStruct {
public long data;
}
public static class ByValue128 extends ByValueStruct {
public long data, data1;
}
final long MAGIC = 0x0123456789ABCDEFL;
public void testStructureArgByValue8() {
ByValue8 data = new ByValue8();
final byte DATA = (byte)MAGIC;
data.data = DATA;
assertEquals("Failed to pass 8-bit struct by value",
DATA, lib.testStructureByValueArgument8(data));
}
public void testStructureArgByValue16() {
ByValue16 data = new ByValue16();
final short DATA = (short)MAGIC;
data.data = DATA;
assertEquals("Failed to pass 16-bit struct by value",
DATA, lib.testStructureByValueArgument16(data));
}
public void testStructureArgByValue32() {
ByValue32 data = new ByValue32();
final int DATA = (int)MAGIC;
data.data = DATA;
assertEquals("Failed to pass 32-bit struct by value",
DATA, lib.testStructureByValueArgument32(data));
}
public void testStructureArgByValue64() {
ByValue64 data = new ByValue64();
final long DATA = (long)MAGIC;
data.data = DATA;
assertEquals("Failed to pass 64-bit struct by value",
DATA, lib.testStructureByValueArgument64(data));
}
public void testStructureArgByValue128() {
ByValue128 data = new ByValue128();
final long DATA = (long)MAGIC;
data.data = DATA;
data.data1 = DATA;
assertEquals("Failed to pass 128-bit struct by value",
2*DATA, lib.testStructureByValueArgument128(data));
}
}
+306 -136
Ver Arquivo
@@ -8,7 +8,7 @@
* 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;
@@ -18,7 +18,6 @@ import java.util.Map;
import junit.framework.TestCase;
import com.sun.jna.IntegerType;
import com.sun.jna.StructureTest.VariableSizeTest.VariableSizedStructure;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
@@ -28,7 +27,7 @@ import com.sun.jna.ptr.LongByReference;
* @author twall@users.sf.net
*/
public class StructureTest extends TestCase {
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(StructureTest.class);
}
@@ -40,7 +39,7 @@ public class StructureTest extends TestCase {
Structure s = new TestStructure();
assertEquals("Wrong size", 4, s.size());
}
// must be public to populate array
public static class TestAllocStructure extends Structure {
public int f0;
@@ -55,17 +54,17 @@ public class StructureTest extends TestCase {
assertEquals("Memory not cleared on structure init", 0, s.f1);
assertEquals("Memory not cleared on structure init", 0, s.f2);
assertEquals("Memory not cleared on structure init", 0, s.f3);
s = (TestAllocStructure)s.toArray(2)[1];
assertEquals("Memory not cleared on array init", 0, s.f0);
assertEquals("Memory not cleared on array init", 0, s.f1);
assertEquals("Memory not cleared on array init", 0, s.f2);
assertEquals("Memory not cleared on array init", 0, s.f3);
}
// cross-platform smoke test
public void testGNUCAlignment() {
class TestStructure extends Structure {
class TestStructure extends Structure {
public byte b;
public short s;
public int i;
@@ -79,10 +78,10 @@ public class StructureTest extends TestCase {
final int SIZE = NativeLong.SIZE == 4 && !isSPARC ? 28 : 32;
assertEquals("Wrong structure size", SIZE, s.size());
}
// cross-platform smoke test
public void testMSVCAlignment() {
class TestStructure extends Structure {
class TestStructure extends Structure {
public byte b;
public short s;
public int i;
@@ -94,7 +93,7 @@ public class StructureTest extends TestCase {
s.setAlignType(Structure.ALIGN_MSVC);
assertEquals("Wrong structure size", 32, s.size());
}
public static class FilledStructure extends Structure {
public FilledStructure() {
for (int i=0;i < size();i++) {
@@ -162,12 +161,12 @@ public class StructureTest extends TestCase {
public void testStructureSize5() {
testStructureSize(5);
}
public interface AlignmentTest extends Library {
int testStructureAlignment(Structure s, int type,
int testStructureAlignment(Structure s, int type,
IntByReference offsetp, LongByReference valuep);
}
private void testAlignStruct(int index) {
AlignmentTest lib = (AlignmentTest)Native.loadLibrary("testlib", AlignmentTest.class);
try {
@@ -176,9 +175,9 @@ public class StructureTest extends TestCase {
Class cls = Class.forName(getClass().getName() + "$TestStructure" + index);
Structure s = (Structure)cls.newInstance();
int result = lib.testStructureAlignment(s, index, offset, value);
assertEquals("Wrong native value at field " + result
+ "=0x" + Long.toHexString(value.getValue())
+ " (actual native field offset=" + offset.getValue()
assertEquals("Wrong native value at field " + result
+ "=0x" + Long.toHexString(value.getValue())
+ " (actual native field offset=" + offset.getValue()
+ ") in " + s, -2, result);
}
catch(Exception e) {
@@ -203,7 +202,7 @@ public class StructureTest extends TestCase {
public void testAlignStruct5() {
testAlignStruct(5);
}
// must be publicly accessible in order to create array elements
public static class PublicTestStructure extends Structure {
public static class ByReference extends PublicTestStructure implements Structure.ByReference { }
@@ -216,12 +215,12 @@ public class StructureTest extends TestCase {
}
TestStructure s = new TestStructure();
assertNotNull("Inner structure should be initialized", s.s1);
assertEquals("Wrong aggregate size",
assertEquals("Wrong aggregate size",
s.s1.size() + s.s2.size() + 4, s.size());
s.write();
s.read();
}
public void testPrimitiveArrayField() {
class TestStructure extends Structure {
public byte[] buffer = new byte[1024];
@@ -232,7 +231,7 @@ public class StructureTest extends TestCase {
s.write();
s.read();
}
public void testStructureArrayField() {
class TestStructure extends Structure {
public PublicTestStructure[] inner = new PublicTestStructure[2];
@@ -242,7 +241,7 @@ public class StructureTest extends TestCase {
TestStructure s = new TestStructure();
int innerSize = new PublicTestStructure().size();
assertEquals("Wrong size for structure with nested array of struct",
s.inner.length * innerSize + s.inner2.length * innerSize,
s.inner.length * innerSize + s.inner2.length * innerSize,
s.size());
s.write();
assertNotNull("Inner array elements should auto-initialize", s.inner[0]);
@@ -253,20 +252,20 @@ public class StructureTest extends TestCase {
0, s.inner[0].x);
assertEquals("Inner structure array element 1 not properly read",
0, s.inner[1].x);
assertEquals("Wrong memory for uninitialized nested array",
s.getPointer(), s.inner[0].getPointer());
assertEquals("Wrong memory for initialized nested array",
s.getPointer().share(innerSize * s.inner.length),
s.getPointer().share(innerSize * s.inner.length),
s.inner2[0].getPointer());
}
public static class ToArrayTestStructure extends Structure {
public PublicTestStructure[] inner =
(PublicTestStructure[])new PublicTestStructure().toArray(2);
}
public void testToArrayWithStructureArrayField() {
ToArrayTestStructure[] array =
ToArrayTestStructure[] array =
(ToArrayTestStructure[])new ToArrayTestStructure().toArray(2);
assertEquals("Wrong address for top-level array element",
array[0].getPointer().share(array[0].size()),
@@ -275,7 +274,7 @@ public class StructureTest extends TestCase {
array[1].inner[0].getPointer().share(array[1].inner[0].size()),
array[1].inner[1].getPointer());
}
public void testUninitializedNestedArrayFails() {
class TestStructure extends Structure {
public Pointer[] buffer;
@@ -295,67 +294,76 @@ public class StructureTest extends TestCase {
// Have to do this due to inline primitive arrays
allocateMemory();
}
public boolean z;
public byte b;
public char c;
public short s;
public int i;
public long j;
public float f;
public double d;
public byte[] ba = new byte[8];
public char[] ca = new char[8];
public short[] sa = new short[8];
public int[] ia = new int[8];
public long[] ja = new long[8];
public float[] fa = new float[8];
public double[] da = new double[8];
public boolean z; // native int
public byte b; // native char
public char c; // native wchar_t
public short s; // native short
public int i; // native int
public long l; // native long long
public float f; // native float
public double d; // native double
public byte[] ba = new byte[3];
public char[] ca = new char[3];
public short[] sa = new short[3];
public int[] ia = new int[3];
public long[] la = new long[3];
public float[] fa = new float[3];
public double[] da = new double[3];
public PublicTestStructure nested;
}
TestStructure s = new TestStructure();
// set content of the structure
s.z = true;
s.b = 1;
s.s = 2;
s.c = 'a';
s.i = 3;
s.j = 4;
s.f = 5;
s.d = 6;
s.c = 2;
s.s = 3;
s.i = 4;
s.l = 5;
s.f = 6.0f;
s.d = 7.0;
s.nested.x = 1;
s.nested.y = 2;
s.ba[0] = 3;
for (int i = 0; i < 3; i++) {
s.ba[i] = (byte) (8 + i);
s.ca[i] = (char) (11 + i);
s.sa[i] = (short) (14 + i);
s.ia[i] = 17 + i;
s.la[i] = 23 + i;
s.fa[i] = (float) 26 + i;
s.da[i] = (double) 29 + i;
}
// write content to memory
s.write();
s.z = false;
s.b = 0;
s.c = 0;
s.s = 0;
s.i = 0;
s.j = 0;
s.f = 0;
s.d = 0;
s.nested.x = s.nested.y = 0;
s.ba[0] = 0;
byte[] ref = s.ba;
Pointer p = s.getPointer();
s = new TestStructure();
s.useMemory(p);
// read content from memory and compare field values
s.read();
assertTrue("Wrong boolean field value after write/read", s.z);
assertEquals("Wrong byte field value after write/read", (byte)1, s.b);
assertEquals("Wrong char field value after write/read",
"'a' (0x" + Integer.toHexString('a') + ")",
"'" + s.c + "' (0x" + Integer.toHexString(s.c) + ")");
assertEquals("Wrong short field value after write/read", 2, s.s);
assertEquals("Wrong int field value after write/read", 3, s.i);
assertEquals("Wrong long field value after write/read", 4, s.j);
assertEquals("Wrong float field value after write/read", 5.0f, s.f);
assertEquals("Wrong double field value after write/read", 6.0d, s.d);
assertEquals("Wrong nested struct field value after write/read (x)",
1, s.nested.x);
assertEquals("Wrong nested struct field value after write/read (y)",
2, s.nested.y);
assertEquals("Wrong nested array element value after write/read",
3, s.ba[0]);
assertSame("Array field reference should be unchanged", ref, s.ba);
assertEquals("Wrong boolean field value after write/read", s.z, true);
assertEquals("Wrong byte field value after write/read", s.b, 1);
assertEquals("Wrong char field value after write/read", s.c, 2);
assertEquals("Wrong short field value after write/read", s.s, 3);
assertEquals("Wrong int field value after write/read", s.i, 4);
assertEquals("Wrong long field value after write/read", s.l, 5);
assertEquals("Wrong float field value after write/read", s.f, 6.0f);
assertEquals("Wrong double field value after write/read", s.d, 7.0);
assertEquals("Wrong nested struct field value after write/read (x)", s.nested.x, 1);
assertEquals("Wrong nested struct field value after write/read (y)", s.nested.y, 2);
for (int i = 0; i < 3; i++) {
assertEquals("Wrong byte array field value after write/read", s.ba[i], (byte) (8 + i));
assertEquals("Wrong char array field value after write/read", s.ca[i], (char) (11 + i));
assertEquals("Wrong short array field value after write/read", s.sa[i], (short) (14 + i));
assertEquals("Wrong int array field value after write/read", s.ia[i], 17 + i);
assertEquals("Wrong long array field value after write/read", s.la[i], 23 + i);
assertEquals("Wrong float array field value after write/read", s.fa[i], (float) 26 + i);
assertEquals("Wrong double array field value after write/read", s.da[i], (double) 29 + i);
}
// test constancy of references after read
int[] ia = s.ia;
s.read();
assertTrue("Array field reference should be unchanged", ia == s.ia);
}
public void testNativeLongSize() throws Exception {
class TestStructure extends Structure {
public NativeLong l;
@@ -363,7 +371,7 @@ public class StructureTest extends TestCase {
Structure s = new TestStructure();
assertEquals("Wrong size", NativeLong.SIZE, s.size());
}
public void testNativeLongRead() throws Exception {
class TestStructure extends Structure {
public int i;
@@ -375,7 +383,7 @@ public class StructureTest extends TestCase {
s.getPointer().setLong(8, MAGIC);
s.read();
assertEquals("NativeLong field mismatch", MAGIC, s.l.longValue());
}
}
else {
final int MAGIC = 0xABEDCF23;
s.getPointer().setInt(4, MAGIC);
@@ -383,7 +391,7 @@ public class StructureTest extends TestCase {
assertEquals("NativeLong field mismatch", MAGIC, s.l.intValue());
}
}
public void testNativeLongWrite() throws Exception {
class TestStructure extends Structure {
public int i;
@@ -396,7 +404,7 @@ public class StructureTest extends TestCase {
s.write();
long l = s.getPointer().getLong(8);
assertEquals("NativeLong field mismatch", MAGIC, l);
}
}
else {
final int MAGIC = 0xABEDCF23;
s.l = new NativeLong(MAGIC);
@@ -405,13 +413,13 @@ public class StructureTest extends TestCase {
assertEquals("NativeLong field mismatch", MAGIC, i);
}
}
public void testDisallowFunctionPointerAsField() {
class BadFieldStructure extends Structure {
public Function cb;
}
try {
BadFieldStructure s = new BadFieldStructure();
new BadFieldStructure().size();
fail("Function fields should not be allowed");
}
catch(IllegalArgumentException e) {
@@ -426,7 +434,7 @@ public class StructureTest extends TestCase {
assertEquals("First element should be original", s, array[0]);
assertEquals("Structure memory should be expanded", 2, s.toArray(2).length);
}
static class CbStruct extends Structure {
public Callback cb;
}
@@ -437,7 +445,6 @@ public class StructureTest extends TestCase {
public TestCallback cb;
}
static interface CbTest extends Library {
public void callCallbackInStruct(CbStruct cbstruct);
public void setCallbackInStruct(CbStruct2 cbstruct);
}
public void testCallbackWrite() {
@@ -454,35 +461,22 @@ public class StructureTest extends TestCase {
CallbackReference ref = (CallbackReference)refs.get(s.cb);
assertEquals("Wrong trampoline", ref.getTrampoline(), func);
}
public void testCallCallbackInStructure() {
final boolean[] flag = {false};
final CbStruct s = new CbStruct();
s.cb = new Callback() {
public void callback() {
flag[0] = true;
}
};
CbTest lib = (CbTest)Native.loadLibrary("testlib", CbTest.class);
lib.callCallbackInStruct(s);
assertTrue("Callback not invoked", flag[0]);
}
public void testReadFunctionPointerAsCallback() {
CbStruct2 s = new CbStruct2();
CbTest lib = (CbTest)Native.loadLibrary("testlib", CbTest.class);
lib.setCallbackInStruct(s);
assertNotNull("Callback field not set", s.cb);
}
public void testCallProxiedFunctionPointer() {
CbStruct2 s = new CbStruct2();
CbTest lib = (CbTest)Native.loadLibrary("testlib", CbTest.class);
lib.setCallbackInStruct(s);
assertEquals("Proxy to native function pointer failed",
assertEquals("Proxy to native function pointer failed",
3, s.cb.callback(1, 2));
}
public void testUninitializedArrayField() {
class UninitializedArrayFieldStructure extends Structure {
public byte[] array;
@@ -495,7 +489,7 @@ public class StructureTest extends TestCase {
catch(IllegalStateException e) {
}
}
public static class ArrayOfStructure extends Structure {
public Structure[] array;
}
@@ -510,7 +504,7 @@ public class StructureTest extends TestCase {
fail("Wrong exception thrown on Structure[] field in Structure: " + e);
}
}
public void testPointerArrayField() {
class ArrayOfPointerStructure extends Structure {
final static int SIZE = 10;
@@ -525,7 +519,7 @@ public class StructureTest extends TestCase {
s.read();
assertEquals("Wrong first element", s.getPointer(), s.array[0]);
}
public void testBufferField() {
// NOTE: may support write-only Buffer fields in the future
class BufferStructure extends Structure {
@@ -535,13 +529,13 @@ public class StructureTest extends TestCase {
}
}
try {
new BufferStructure(new byte[1024]);
fail("Buffer fields should fail immediately");
new BufferStructure(new byte[1024]).size();
fail("Buffer fields should not be allowed");
}
catch(IllegalArgumentException e) {
catch(IllegalArgumentException e) {
}
}
public void testVolatileStructureField() {
class VolatileStructure extends Structure {
public volatile int counter;
@@ -565,13 +559,13 @@ public class StructureTest extends TestCase {
StructureWithPointers s = new StructureWithPointers();
assertEquals("Wrong size for structure with structure references",
Pointer.SIZE * 2, s.size());
assertNull("Initial refs should be null", s.s1);
}
public void testRegenerateStructureByReferenceField() {
StructureWithPointers s = new StructureWithPointers();
PublicTestStructure.ByReference inner =
PublicTestStructure.ByReference inner =
new PublicTestStructure.ByReference();
s.s1 = inner;
s.write();
@@ -580,24 +574,39 @@ public class StructureTest extends TestCase {
assertEquals("Inner structure not regenerated on read", inner, s.s1);
}
public void testPreserveStructureByReferenceWithUnchangedPointer() {
public void testPreserveStructureByReferenceWithUnchangedPointerOnRead() {
StructureWithPointers s = new StructureWithPointers();
PublicTestStructure.ByReference inner =
PublicTestStructure.ByReference inner =
new PublicTestStructure.ByReference();
s.s1 = inner;
s.write();
s.read();
assertSame("Read should preserve structure object", inner, s.s1);
assertTrue("Read should preserve structure memory",
assertSame("Read should preserve structure object", inner, s.s1);
assertTrue("Read should preserve structure memory",
inner.getPointer() instanceof Memory);
}
public void testOverwriteStructureByReferenceField() {
public static class TestPointer extends PointerType { }
public void testPreservePointerFields() {
class TestStructure extends Structure {
public Pointer p = new Memory(256);
public TestPointer p2 = new TestPointer() {
{ setPointer(new Memory(256)); }
};
}
TestStructure s = new TestStructure();
final Pointer p = s.p;
s.write();
s.read();
assertSame("Should preserve Pointer references if peer unchanged", p, s.p);
}
public void testOverwriteStructureByReferenceFieldOnRead() {
StructureWithPointers s = new StructureWithPointers();
PublicTestStructure.ByReference inner =
PublicTestStructure.ByReference inner =
new PublicTestStructure.ByReference();
PublicTestStructure.ByReference inner2 =
PublicTestStructure.ByReference inner2 =
new PublicTestStructure.ByReference();
s.s1 = inner2;
s.write();
@@ -605,27 +614,36 @@ public class StructureTest extends TestCase {
s.read();
assertNotSame("Read should overwrite structure reference", inner, s.s1);
}
public void testAutoWriteStructureByReferenceField() {
StructureWithPointers s = new StructureWithPointers();
s.s1 = new StructureTest.PublicTestStructure.ByReference();
s.s1.x = -1;
s.write();
assertEquals("Structure.ByReference not written automatically",
-1, s.s1.getPointer().getInt(0));
}
public void testStructureByReferenceArrayField() {
class TestStructure extends Structure {
public PublicTestStructure.ByReference[] array = new PublicTestStructure.ByReference[2];
}
TestStructure s = new TestStructure();
assertEquals("Wrong structure size", 2*Pointer.SIZE, s.size());
PublicTestStructure.ByReference ref = new PublicTestStructure.ByReference();
ref.x = 42;
Object aref = s.array;
s.array[0] = ref;
s.array[1] = new PublicTestStructure.ByReference();
s.write();
s.read();
assertSame("Array reference should not change", aref, s.array);
assertSame("Elements should not be overwritten when unchanged",
assertSame("Elements should not be overwritten when unchanged",
ref, s.array[0]);
s.array[0] = null;
s.read();
assertNotSame("Null should be overwritten with a new ref", ref, s.array[0]);
@@ -646,7 +664,7 @@ public class StructureTest extends TestCase {
}
public void testNestedStructureTypeInfo() {
class FFIType extends Structure {
public FFIType(Pointer p) {
public FFIType(Pointer p) {
useMemory(p); read();
}
public size_t size;
@@ -665,10 +683,10 @@ public class StructureTest extends TestCase {
assertEquals("Wrong type information for integer field",
Structure.getTypeInfo(new Integer(0)),
els.getPointer(Pointer.SIZE));
assertNull("Type element list should be null-terminated",
assertNull("Type element list should be null-terminated",
els.getPointer(Pointer.SIZE*2));
}
public void testInnerArrayTypeInfo() {
class TestStructure extends Structure {
public int[] inner = new int[5];
@@ -678,13 +696,13 @@ public class StructureTest extends TestCase {
Pointer p = s.getTypeInfo();
assertNotNull("Type info should not be null", p);
}
public void testTypeInfoForNull() {
assertEquals("Wrong type information for 'null'",
Structure.getTypeInfo(new Pointer(0)),
Structure.getTypeInfo(null));
}
public void testToString() {
class TestStructure extends Structure {
public int intField;
@@ -693,7 +711,7 @@ public class StructureTest extends TestCase {
TestStructure s = new TestStructure();
final String LS = System.getProperty("line.separator");
System.setProperty("jna.dump_memory", "true");
final String EXPECTED = "(?m).*" + s.size() + " bytes.*\\{" + LS
final String EXPECTED = "(?m).*" + s.size() + " bytes.*\\{" + LS
+ " int intField@0=0" + LS
+ " .* inner@4=.*\\{" + LS
+ " int x@0=0" + LS
@@ -705,11 +723,11 @@ public class StructureTest extends TestCase {
+ "\\[00000000\\]" + LS
+ "\\[00000000\\]";
String actual = s.toString();
assertTrue("Improperly formatted toString(): expected "
+ EXPECTED + "\n" + actual,
assertTrue("Improperly formatted toString(): expected "
+ EXPECTED + "\n" + actual,
actual.matches(EXPECTED));
}
public interface VariableSizeTest extends Library {
public static class VariableSizedStructure extends Structure {
public int length;
@@ -729,7 +747,7 @@ public class StructureTest extends TestCase {
assertEquals("Wrong string returned from variable sized struct",
EXPECTED, lib.returnStringFromVariableSizedStructure(s));
}
public void testNativeMappedWrite() {
class TestStructure extends Structure {
public ByteByReference ref;
@@ -738,4 +756,156 @@ public class StructureTest extends TestCase {
s.ref = null;
s.write();
}
public static class ROStructure extends Structure {
public final int field;
{
field = 0;
getPointer().setInt(0, 42);
read();
}
}
public void testReadOnlyField() {
ROStructure s = new ROStructure();
assertEquals("Field value should be writable from native", 42, s.field);
}
public void testNativeMappedArrayField() {
final int SIZE = 24;
class TestStructure extends Structure {
public NativeLong[] longs = new NativeLong[SIZE];
}
TestStructure s = new TestStructure();
assertEquals("Wrong structure size", Native.LONG_SIZE * SIZE, s.size());
NativeLong[] aref = s.longs;
for (int i=0;i < s.longs.length;i++) {
s.longs[i] = new NativeLong(i);
}
s.write();
for (int i=0;i < s.longs.length;i++) {
assertEquals("Value not written to memory at index " + i,
i, s.getPointer().getNativeLong(i * NativeLong.SIZE).intValue());
}
s.read();
assertEquals("Array reference should remain unchanged on read",
aref, s.longs);
for (int i=0;i < s.longs.length;i++) {
assertEquals("Wrong value after read at index " + i,
i, s.longs[i].intValue());
}
}
public void testInitializeNativeMappedField() {
final long VALUE = 20;
final NativeLong INITIAL = new NativeLong(VALUE);
class TestStructure extends Structure {
// field overwritten, wrong value before write
// NL bug, wrong value written
{ setAlignType(ALIGN_NONE); }
public NativeLong nl = INITIAL;
public NativeLong uninitialized;
}
TestStructure ts = new TestStructure();
assertEquals("Wrong value in field", VALUE, ts.nl.longValue());
assertSame("Initial value overwritten", INITIAL, ts.nl);
assertEquals("Wrong field value before write", VALUE, ts.nl.longValue());
assertNotNull("Uninitialized field should be initialized", ts.uninitialized);
assertEquals("Wrong initialized value", 0, ts.uninitialized.longValue());
ts.write();
assertEquals("Wrong field value written", VALUE, ts.getPointer().getNativeLong(0).longValue());
assertEquals("Wrong field value written (2)", 0, ts.getPointer().getNativeLong(NativeLong.SIZE).longValue());
ts.read();
assertEquals("Wrong field value", VALUE, ts.nl.longValue());
assertEquals("Wrong field value (2)", 0, ts.uninitialized.longValue());
}
public void testStructureFieldOrder() {
Structure.REQUIRES_FIELD_ORDER = true;
try {
class TestStructure extends Structure {
public int one = 1;
public int three = 3;
public int two = 2;
{
setFieldOrder(new String[] { "one", "two", "three" });
}
}
class DerivedTestStructure extends TestStructure {
public int four = 4;
{
setFieldOrder(new String[] { "four" });
}
}
DerivedTestStructure s = new DerivedTestStructure();
DerivedTestStructure s2 = new DerivedTestStructure();
s.write();
s2.write();
assertEquals("Wrong first field", 1, s.getPointer().getInt(0));
assertEquals("Wrong second field", 2, s.getPointer().getInt(4));
assertEquals("Wrong third field", 3, s.getPointer().getInt(8));
assertEquals("Wrong derived field", 4, s.getPointer().getInt(12));
}
finally {
Structure.REQUIRES_FIELD_ORDER = false;
}
}
public void testCustomTypeMapper() {
class TestField { }
class TestStructure extends Structure {
public TestField field;
public TestStructure() {
DefaultTypeMapper m = new DefaultTypeMapper();
m.addTypeConverter(TestField.class, new TypeConverter() {
public Object fromNative(Object value, FromNativeContext context) {
return new TestField();
}
public Class nativeType() {
return String.class;
}
public Object toNative(Object value, ToNativeContext ctx) {
return value == null ? null : value.toString();
}
});
setTypeMapper(new DefaultTypeMapper());
}
}
new TestStructure();
}
public void testWriteWithNullBoxedPrimitives() {
class TestStructure extends Structure {
public Boolean zfield;
public Integer field;
}
TestStructure s = new TestStructure();
s.write();
s.read();
assertNotNull("Field should not be null after read", s.field);
}
public interface AutoSynchTest extends Library {
public static class TestStructure extends Structure {
public int field;
}
Pointer testStructurePointerArgument(TestStructure s);
}
public void testDisableAutoSynch() {
AutoSynchTest lib = (AutoSynchTest)Native.loadLibrary("testlib", AutoSynchTest.class);
AutoSynchTest.TestStructure s = new AutoSynchTest.TestStructure();
final int VALUE = 42;
s.field = VALUE;
s.setAutoWrite(false);
lib.testStructurePointerArgument(s);
assertEquals("Auto write should be disabled", 0, s.field);
final int EXPECTED = s.field;
s.getPointer().setInt(0, VALUE);
s.setAutoRead(false);
lib.testStructurePointerArgument(s);
assertEquals("Auto read should be disabled", EXPECTED, s.field);
}
}
-37
Ver Arquivo
@@ -173,43 +173,6 @@ public class TypeMapperTest extends TestCase {
assertFalse("Wrong value read", s.data);
}
public static interface CallbackTestLibrary extends Library {
interface Int32Callback extends Callback {
float callback(float arg, float arg2);
}
float callInt32Callback(Int32Callback c, float arg, float arg2);
}
public void testCallbackTypeMapping() throws Exception {
final DefaultTypeMapper mapper = new DefaultTypeMapper();
Map options = new HashMap() {
{ put(Library.OPTION_TYPE_MAPPER, mapper); }
};
CallbackTestLibrary lib = (CallbackTestLibrary)
Native.loadLibrary("testlib", CallbackTestLibrary.class, options);
// Convert java floats into native integers and back
TypeConverter converter = new TypeConverter() {
public Object fromNative(Object value, FromNativeContext context) {
return new Float(((Integer)value).intValue());
}
public Class nativeType() {
return Integer.class;
}
public Object toNative(Object value, ToNativeContext ctx) {
return new Integer(Math.round(((Float)value).floatValue()));
}
};
mapper.addTypeConverter(float.class, converter);
CallbackTestLibrary.Int32Callback cb = new CallbackTestLibrary.Int32Callback() {
public float callback(float arg, float arg2) {
return arg + arg2;
}
};
assertEquals("Wrong result", 0, lib.callInt32Callback(cb, 0, 0), 0);
assertEquals("Wrong result", 1, lib.callInt32Callback(cb, 0, 1), 0);
assertEquals("Wrong result", 2, lib.callInt32Callback(cb, 1, 1), 0);
assertEquals("Wrong result", -2, lib.callInt32Callback(cb, -1, -1), 0);
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface FooBoolean {}
+62
Ver Arquivo
@@ -20,6 +20,16 @@ public class UnionTest extends TestCase {
public String value;
}
public static class IntStructure extends Structure {
public int value;
}
public static class SubIntStructure extends IntStructure {}
public static interface Func1 extends Callback {
public void callback();
}
public static class SizedUnion extends Union {
public byte byteField;
public short shortField;
@@ -31,6 +41,13 @@ public class UnionTest extends TestCase {
public Pointer pointer;
}
public static class StructUnion extends Union {
public int intField;
public TestStructure testStruct;
public IntStructure intStruct;
public Func1 func1;
}
public void testCalculateSize() {
Union u = new SizedUnion();
assertEquals("Union should be size of largest field", 8, u.size());
@@ -60,6 +77,39 @@ public class UnionTest extends TestCase {
assertNull("Unselected WString should be null", u.wstring);
}
public void testWriteTypedUnion() {
final int VALUE = 0x12345678;
// write an instance of a direct union class to memory
StructUnion u = new StructUnion();
IntStructure intStruct = new IntStructure();
intStruct.value = VALUE;
u.setTypedValue(intStruct);
u.write();
assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0));
// write an instance of a sub class of an union class to memory
u = new StructUnion();
SubIntStructure subIntStructure = new SubIntStructure();
subIntStructure.value = VALUE;
u.setTypedValue(subIntStructure);
u.write();
assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0));
// write an instance of an interface
u = new StructUnion();
Func1 func1 = new Func1() {
public void callback() {
System.out.println("hi");
}
};
u.setTypedValue(func1);
}
public void testReadTypedUnion() {
StructUnion u = new StructUnion();
final int VALUE = 0x12345678;
u.getPointer().setInt(0, VALUE);
assertEquals("int structure not read properly", VALUE, ((IntStructure) u.getTypedValue(IntStructure.class)).value);
}
public void testReadTypeInfo() {
SizedUnion u = new SizedUnion();
assertEquals("Type should be that of longest field if no field active",
@@ -71,6 +121,18 @@ public class UnionTest extends TestCase {
u.getTypeInfo());
}
public void testArraysInUnion() {
class TestUnion extends Union {
public byte[] bytes = new byte[16];
public short[] shorts = new short[8];
public int[] ints = new int[4];
}
Union u = new TestUnion();
u.setType(byte[].class);
u.setType(short[].class);
u.setType(int[].class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(UnionTest.class);
}
@@ -21,21 +21,18 @@ import junit.framework.TestCase;
import com.sun.jna.Platform;
import com.sun.jna.examples.FileMonitor.FileEvent;
import com.sun.jna.examples.FileMonitor.FileListener;
import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.ptr.PointerByReference;
public class FileMonitorTest extends TestCase {
Map events;
FileListener listener;
FileMonitor monitor;
File tmpdir;
private Map events;
private FileMonitor monitor;
private File tmpdir;
protected void setUp() throws Exception {
if (!Platform.isWindows()) return;
events = new HashMap();
listener = new FileListener() {
final FileListener listener = new FileListener() {
public void fileChanged(FileEvent e) {
events.put(new Integer(e.getType()), e);
}
@@ -57,15 +54,7 @@ public class FileMonitorTest extends TestCase {
monitor.addWatch(tmpdir);
File file = File.createTempFile(getName(), ".tmp", tmpdir);
file.deleteOnExit();
FileEvent event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
}
assertTrue("No events sent", events.size() != 0);
assertNotNull("No creation event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
assertFileEventCreated(file);
}
public void testNotifyOnFileDelete() throws Exception {
@@ -74,17 +63,24 @@ public class FileMonitorTest extends TestCase {
monitor.addWatch(tmpdir);
File file = File.createTempFile(getName(), ".tmp", tmpdir);
file.delete();
FileEvent event = (FileEvent)events.get(new Integer(FileMonitor.FILE_DELETED));
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_DELETED));
}
assertTrue("No events sent", events.size() != 0);
final FileEvent event = waitForFileEvent(FileMonitor.FILE_DELETED);
assertNotNull("No delete event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
}
public void testNotifyOnFileDeleteViaAddWatchMask() throws Exception {
if (!Platform.isWindows()) return;
monitor.addWatch(tmpdir, FileMonitor.FILE_DELETED);
File file = File.createTempFile(getName(), ".tmp", tmpdir);
file.delete();
final FileEvent event = waitForFileEvent(FileMonitor.FILE_DELETED);
assertNotNull("No delete event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
}
public void testNotifyOnFileRename() throws Exception {
if (!Platform.isWindows()) return;
@@ -94,19 +90,13 @@ public class FileMonitorTest extends TestCase {
newFile.deleteOnExit();
file.deleteOnExit();
file.renameTo(newFile);
FileEvent e1 = (FileEvent)events.get(new Integer(FileMonitor.FILE_NAME_CHANGED_OLD));
FileEvent e2 = (FileEvent)events.get(new Integer(FileMonitor.FILE_NAME_CHANGED_NEW));
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && e1 == null && e2 == null) {
Thread.sleep(10);
e1 = (FileEvent)events.get(new Integer(FileMonitor.FILE_NAME_CHANGED_OLD));
e2 = (FileEvent)events.get(new Integer(FileMonitor.FILE_NAME_CHANGED_NEW));
}
assertTrue("No events sent", events.size() != 0);
assertNotNull("No rename event (old): " + events, e1);
assertNotNull("No rename event (new): " + events, e2);
assertEquals("Wrong target file for event (old)", file, e1.getFile());
assertEquals("Wrong target file for event (new)", newFile, e2.getFile());
final FileEvent eventFilenameOld = waitForFileEvent(FileMonitor.FILE_NAME_CHANGED_OLD);
final FileEvent eventFilenameNew = waitForFileEvent(FileMonitor.FILE_NAME_CHANGED_NEW);
assertNotNull("No rename event (old): " + events, eventFilenameOld);
assertNotNull("No rename event (new): " + events, eventFilenameNew);
assertEquals("Wrong target file for event (old)", file, eventFilenameOld.getFile());
assertEquals("Wrong target file for event (new)", newFile, eventFilenameNew.getFile());
}
public void testNotifyOnFileModification() throws Exception {
@@ -115,16 +105,13 @@ public class FileMonitorTest extends TestCase {
monitor.addWatch(tmpdir);
File file = File.createTempFile(getName(), ".tmp", tmpdir);
file.deleteOnExit();
FileOutputStream os = new FileOutputStream(file);
os.write(getName().getBytes());
os.close();
FileEvent event = (FileEvent)events.get(new Integer(FileMonitor.FILE_MODIFIED));
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_MODIFIED));
final FileOutputStream os = new FileOutputStream(file);
try {
os.write(getName().getBytes());
} finally {
os.close();
}
assertTrue("No events sent", events.size() != 0);
final FileEvent event = waitForFileEvent(FileMonitor.FILE_MODIFIED);
assertNotNull("No file modified event: " + events, event);
assertEquals("Wrong target file for event (old)", file, event.getFile());
}
@@ -147,48 +134,20 @@ public class FileMonitorTest extends TestCase {
public void testMultipleWatches() throws Exception {
if (!Platform.isWindows()) return;
File subdir1 = createSubdir(tmpdir, "sub1");
File subdir2 = createSubdir(tmpdir, "sub2");
File subdir1 = createSubdir(tmpdir, "sub1-");
File subdir2 = createSubdir(tmpdir, "sub2-");
try {
monitor.addWatch(subdir1);
monitor.addWatch(subdir2);
// trigger change in dir 1
File file = File.createTempFile(getName(), ".tmp", subdir1);
FileEvent event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
}
assertTrue("No events sent", events.size() != 0);
assertNotNull("No creation event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
events.clear();
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir1));
// trigger change in dir 2
file = File.createTempFile(getName(), ".tmp", subdir2);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
}
assertTrue("No events sent", events.size() != 0);
assertNotNull("No creation event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir2));
// trigger change in dir 1
file = File.createTempFile(getName(), ".tmp", subdir1);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && event == null) {
Thread.sleep(10);
event = (FileEvent)events.get(new Integer(FileMonitor.FILE_CREATED));
}
assertTrue("No events sent", events.size() != 0);
assertNotNull("No creation event: " + events, event);
assertEquals("Wrong target file for event", file, event.getFile());
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir1));
}
finally {
delete(subdir1);
@@ -196,6 +155,60 @@ public class FileMonitorTest extends TestCase {
}
}
public void testMultipleConsecutiveWatches() throws Exception {
if (!Platform.isWindows()) return;
File subdir1 = createSubdir(tmpdir, "sub1-");
File subdir2 = createSubdir(tmpdir, "sub2-");
try {
monitor.addWatch(subdir1);
monitor.addWatch(subdir2);
// trigger change in dir 1
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir1));
monitor.removeWatch(subdir1);
// trigger change in dir 2
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir2));
monitor.removeWatch(subdir2);
monitor.addWatch(subdir1);
// assertion below has intermittent failures on slow W2K box w/out sleep
Thread.sleep(10);
// trigger change in dir 1
assertFileEventCreated(File.createTempFile(getName(), ".tmp", subdir1));
monitor.removeWatch(subdir1);
}
finally {
delete(subdir1);
delete(subdir2);
}
}
private void assertFileEventCreated(final File expectedFile)
throws InterruptedException {
final FileEvent actualEvent = waitForFileEvent(FileMonitor.FILE_CREATED);
assertNotNull("No creation event: " + events, actualEvent);
assertEquals("Wrong target file for event", expectedFile, actualEvent.getFile());
events.clear();
}
private FileEvent waitForFileEvent(final int expectedFileEvent)
throws InterruptedException {
final Integer expectedFileEventInteger = new Integer(expectedFileEvent);
FileEvent actualEvent = (FileEvent)events.get(expectedFileEventInteger);
final long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 5000 && actualEvent == null) {
Thread.sleep(10);
actualEvent = (FileEvent) events.get(expectedFileEventInteger);
}
assertTrue("No events sent", events.size() != 0);
return actualEvent;
}
public static void main(String[] args) {
junit.textui.TestRunner.run(FileMonitorTest.class);
}
@@ -13,6 +13,7 @@
package com.sun.jna.examples;
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
public class FileUtilsTest extends TestCase {
@@ -26,7 +27,12 @@ public class FileUtilsTest extends TestCase {
File file = File.createTempFile(getName(), ".tmp", home);
try {
assertTrue("File should exist", file.exists());
assertTrue("Move to trash failed", utils.moveToTrash(new File[] { file }));
try {
utils.moveToTrash(new File[] { file });
}
catch(IOException e) {
fail(e.toString());
}
assertFalse("Failed to move " + file + " to trash", file.exists());
}
finally {
@@ -0,0 +1,92 @@
/* Copyright (c) 2008 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.
*/
package com.sun.jna.examples;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import com.sun.jna.examples.RasterRangesUtils.RangesOutput;
public class RasterRangesUtilsTest extends TestCase {
Set rects = new HashSet();
RangesOutput out = new RangesOutput() {
public boolean outputRange(int x, int y, int w, int h) {
rects.add(new Rectangle(x, y, w, h));
return true;
}
};
private Raster createRaster(Shape mask) {
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.fill(mask);
g.dispose();
return image.getRaster();
}
public void testDecomposeRectangles() {
Set EXPECTED = new HashSet() {
{
add(new Rectangle(0, 0, 100, 50));
add(new Rectangle(0, 50, 50, 50));
}
};
Area mask = new Area(new Rectangle(0, 0, 100, 100));
mask.subtract(new Area(new Rectangle(50, 50, 50, 50)));
RasterRangesUtils.outputOccupiedRanges(createRaster(mask), out);
assertEquals("Wrong number of rectangles", EXPECTED.size(), rects.size());
assertEquals("Wrong rectangles", EXPECTED, rects);
}
public void testDecomposeRectanglesWithHole() {
Set EXPECTED = new HashSet() {
{
add(new Rectangle(0, 0, 100, 25));
add(new Rectangle(0, 25, 25, 50));
add(new Rectangle(75, 25, 25, 50));
add(new Rectangle(0, 75, 100, 25));
}
};
Area mask = new Area(new Rectangle(0, 0, 100, 100));
mask.subtract(new Area(new Rectangle(25, 25, 50, 50)));
RasterRangesUtils.outputOccupiedRanges(createRaster(mask), out);
assertEquals("Wrong number of rectangles", EXPECTED.size(), rects.size());
assertEquals("Wrong rectangles", EXPECTED, rects);
/*
long start = System.currentTimeMillis();
for (int i=0;i < 100;i++) {
RasterRangesUtils.outputOccupiedRanges(createRaster(mask), out);
}
System.out.println("raster: " + (System.currentTimeMillis()-start));
*/
}
public static void main(String[] args) {
junit.textui.TestRunner.run(RasterRangesUtilsTest.class);
}
}
@@ -15,21 +15,29 @@ package com.sun.jna.examples.win32;
import java.util.Calendar;
import java.util.TimeZone;
import junit.framework.TestCase;
import com.sun.jna.Platform;
public class Kernel32Test extends TestCase {
public void testGetDriveType() {
if (!Platform.isWindows()) return;
Kernel32 kernel = Kernel32.INSTANCE;
assertEquals("Wrong drive type.", Kernel32.DRIVE_FIXED, kernel.GetDriveType("c:"));
}
public void testStructureOutArgument() {
Kernel32 kernel = Kernel32.INSTANCE;
Kernel32.SYSTEMTIME time = new Kernel32.SYSTEMTIME();
kernel.GetSystemTime(time);
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
assertEquals("Hour not properly set",
cal.get(Calendar.HOUR_OF_DAY), time.wHour);
assertEquals("Day not properly set",
cal.get(Calendar.DAY_OF_WEEK)-1,
time.wDayOfWeek);
assertEquals("Hour not properly set",
cal.get(Calendar.HOUR_OF_DAY), time.wHour);
assertEquals("Day not properly set",
cal.get(Calendar.DAY_OF_WEEK)-1,
time.wDayOfWeek);
assertEquals("Year not properly set",
cal.get(Calendar.YEAR), time.wYear);
cal.get(Calendar.YEAR), time.wYear);
}
public void testGetLastError() {
@@ -40,10 +48,10 @@ public class Kernel32Test extends TestCase {
int code = kernel.GetLastError();
assertEquals("Wrong error value after SetLastError", ERRCODE, code);
if (kernel.GetProcessId(null) == 0) {
final int INVALID_HANDLE = 6;
if (kernel.GetProcessVersion(-1) == 0) {
final int INVALID_PARAMETER = 87;
code = kernel.GetLastError();
assertEquals("Wrong error value after failed syscall", INVALID_HANDLE, code);
assertEquals("Wrong error value after failed syscall", INVALID_PARAMETER, code);
}
else {
fail("GetProcessId(NULL) should fail");
@@ -12,12 +12,19 @@
*/
package com.sun.jna.examples.win32;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import junit.framework.TestCase;
public class Shell32Test extends TestCase {
public static void main(String[] args) {
junit.textui.TestRunner.run(Shell32Test.class);
}
public void testStructurePacking() {
Structure s = new Shell32.SHFILEOPSTRUCT();
assertEquals("Wrong structure size", 30, s.size());
final int SIZE = Pointer.SIZE * 5 + 10; // 5 pointers, 2 ints, 1 short
assertEquals("Wrong structure size", SIZE, s.size());
}
}
@@ -14,6 +14,7 @@ package com.sun.jna.win32;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.W32API;
import junit.framework.TestCase;
@@ -22,6 +23,10 @@ public class W32APIMapperTest extends TestCase {
final String MAGIC = "magic";
public static void main(String[] args) {
junit.textui.TestRunner.run(W32APIMapperTest.class);
}
public interface UnicodeLibrary extends Library {
public static class TestStructure extends Structure {
public String string;
@@ -89,40 +94,42 @@ public class W32APIMapperTest extends TestCase {
public void testUnicodeStructureSize() {
UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure();
assertEquals("Wrong structure size", 16, s.size());
assertEquals("Wrong structure size",
Pointer.SIZE*2+8, s.size());
}
public void testASCIIStructureSize() {
ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure();
assertEquals("Wrong structure size", 16, s.size());
assertEquals("Wrong structure size",
Pointer.SIZE*2+8, s.size());
}
public void testUnicodeStructureWriteBoolean() {
UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure();
s.bool2 = true;
s.write();
assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(8));
assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(12));
assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(Pointer.SIZE*2));
assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(Pointer.SIZE*2+4));
}
public void testASCIIStructureWriteBoolean() {
ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure();
s.bool2 = true;
s.write();
assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(8));
assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(12));
assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(Pointer.SIZE*2));
assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(Pointer.SIZE*2+4));
}
public void testUnicodeStructureReadBoolean() {
UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure();
s.getPointer().setInt(8, 1);
s.getPointer().setInt(12, 0);
s.getPointer().setInt(Pointer.SIZE*2, 1);
s.getPointer().setInt(Pointer.SIZE*2+4, 0);
s.read();
assertTrue("Wrong value read for TRUE", s.bool);
assertFalse("Wrong value read for FALSE", s.bool2);
}
public void testASCIIStructureReadBoolean() {
ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure();
s.getPointer().setInt(8, 1);
s.getPointer().setInt(12, 0);
s.getPointer().setInt(Pointer.SIZE*2, 1);
s.getPointer().setInt(Pointer.SIZE*2+4, 0);
s.read();
assertTrue("Wrong value read for TRUE", s.bool);
assertFalse("Wrong value read for FALSE", s.bool2);
@@ -133,7 +140,7 @@ public class W32APIMapperTest extends TestCase {
s.string2 = MAGIC;
s.write();
assertEquals("Improper null write", null, s.getPointer().getPointer(0));
assertEquals("Improper string write", MAGIC, s.getPointer().getPointer(4).getString(0, true));
assertEquals("Improper string write", MAGIC, s.getPointer().getPointer(Pointer.SIZE).getString(0, true));
}
public void testASCIIStructureWriteString() {
ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure();
@@ -141,7 +148,7 @@ public class W32APIMapperTest extends TestCase {
s.string2 = MAGIC;
s.write();
assertEquals("Improper null write", null, s.getPointer().getPointer(0));
assertEquals("Improper string write", MAGIC, s.getPointer().getPointer(4).getString(0, false));
assertEquals("Improper string write", MAGIC, s.getPointer().getPointer(Pointer.SIZE).getString(0, false));
}
public void testUnicodeStructureReadString() {
UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure();
+25 -11
Ver Arquivo
@@ -17,6 +17,7 @@ import java.util.HashMap;
import junit.framework.TestCase;
import com.sun.jna.FunctionMapper;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
@@ -65,18 +66,31 @@ public class W32StdCallTest extends TestCase {
}
public void testFunctionMapper() throws Exception {
FunctionMapper mapper = StdCallLibrary.FUNCTION_MAPPER;
NativeLibrary lib = NativeLibrary.getInstance("testlib");
Method m = TestLibrary.class.getMethod("returnInt32ArgumentStdCall", new Class[] { int.class });
assertEquals("Function mapper should provide decorated name",
"returnInt32ArgumentStdCall@" + Native.getNativeSize(int.class),
StdCallLibrary.FUNCTION_MAPPER.getFunctionName(lib, m));
Class type = TestLibrary.TestStructure.ByValue.class;
m = TestLibrary.class.getMethod("returnStructureByValueArgumentStdCall",
new Class[] { type });
assertEquals("Function mapper should provide decorated name for by-value structs",
"returnStructureByValueArgumentStdCall@" + Native.getNativeSize(type),
StdCallLibrary.FUNCTION_MAPPER.getFunctionName(lib, m));
Method[] methods = {
TestLibrary.class.getMethod("returnInt32ArgumentStdCall",
new Class[] { int.class }),
TestLibrary.class.getMethod("returnStructureByValueArgumentStdCall",
new Class[] {
TestLibrary.TestStructure.ByValue.class
}),
TestLibrary.class.getMethod("callInt32StdCallCallback",
new Class[] {
TestLibrary.Int32Callback.class,
int.class, int.class,
}),
};
for (int i=0;i < methods.length;i++) {
String name = mapper.getFunctionName(lib, methods[i]);
assertTrue("Function name not decorated for method "
+ methods[i].getName()
+ ": " + name, name.indexOf("@") != -1);
assertEquals("Wrong name in mapped function",
name, lib.getFunction(name, StdCallLibrary.STDCALL_CONVENTION).getName());
}
}
public void testStdCallReturnInt32Argument() {
+7 -1
Ver Arquivo
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generic JNLP/Web Start Configuration -->
<jnlp spec="1.0" codebase="http://abbot.sf.net/demo" href="http://jna.dev.java.net/demo/BalloonManagerDemo.jnlp">
<jnlp spec="1.0" codebase="http://abbot.sf.net/demo" href="https://jna.dev.java.net/demo/BalloonManagerDemo.jnlp">
<information>
<title>Balloon Manager Demo</title>
<vendor>Java Native Access (JNA)</vendor>
@@ -18,6 +18,9 @@
<resources os="Windows" arch="x86">
<nativelib href="win32-x86.jar"/>
</resources>
<resources os="Windows" arch="amd64">
<nativelib href="win32-amd64.jar"/>
</resources>
<resources os="Linux" arch="i386">
<!-- Use 32-bit X11 libs on 64-bit systems (Ubuntu) -->
<property name="jna.library.path" value="/usr/X11R6/lib:/usr/lib32:/usr/lib"/>
@@ -27,6 +30,9 @@
<property name="jna.library.path" value="/usr/X11R6/lib:/usr/lib"/>
<nativelib href="linux-amd64.jar"/>
</resources>
<resources os="OpenBSD" arch="i386">
<nativelib href="openbsd-i386.jar"/>
</resources>
<resources os="FreeBSD" arch="i386">
<nativelib href="freebsd-i386.jar"/>
</resources>
+7 -1
Ver Arquivo
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generic JNLP/Web Start Configuration -->
<jnlp spec="1.0" codebase="http://abbot.sf.net/demo" href="http://jna.dev.java.net/demo/ShapedWindowDemo.jnlp">
<jnlp spec="1.0" codebase="http://abbot.sf.net/demo" href="https://jna.dev.java.net/demo/ShapedWindowDemo.jnlp">
<information>
<title>Shaped Window Demo</title>
<vendor>Java Native Access (JNA)</vendor>
@@ -18,6 +18,9 @@
<resources os="Windows" arch="x86">
<nativelib href="win32-x86.jar"/>
</resources>
<resources os="Windows" arch="amd64">
<nativelib href="win32-amd64.jar"/>
</resources>
<resources os="Linux" arch="i386">
<!-- Use 32-bit X11 libs on 64-bit systems (Ubuntu) -->
<property name="jna.library.path" value="/usr/X11R6/lib:/usr/lib32:/usr/lib"/>
@@ -27,6 +30,9 @@
<property name="jna.library.path" value="/usr/X11R6/lib:/usr/lib"/>
<nativelib href="linux-amd64.jar"/>
</resources>
<resources os="OpenBSD" arch="i386">
<nativelib href="openbsd-i386.jar"/>
</resources>
<resources os="FreeBSD" arch="i386">
<nativelib href="freebsd-i386.jar"/>
</resources>
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.

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