Comparar commits

...

219 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
Timothy Wall f121b6c039 tweak
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@513 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 19:51:55 +00:00
Timothy Wall c48b13bc0a update examples jar
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@512 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 19:36:20 +00:00
Timothy Wall 26abb9beb9 update examples jar
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@511 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 19:34:44 +00:00
Timothy Wall 02cc7d53b7 update demos
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@510 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 19:28:35 +00:00
Timothy Wall 67136b5986 update linux-amd64 native
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@509 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 13:50:40 +00:00
Timothy Wall 58d5175fde fix w32 api type mapper bug exposed by last round of changes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@508 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 13:43:23 +00:00
Timothy Wall c511c4063e use 'JNI_FALSE' rather than 'false'
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@507 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:43:23 +00:00
Timothy Wall 6429611b3c include sunos-amd64
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@506 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:32:45 +00:00
Timothy Wall 3cea53ddca bump version on jna.jar to 3.0.2
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@505 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:29:50 +00:00
Timothy Wall d661e58fc3 bump version, include new architectures
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@504 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:28:13 +00:00
Timothy Wall e140b6e4e2 Disable inapplicable test on OSX
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@503 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:19:47 +00:00
Timothy Wall e1025d9337 Use UTF8 encoding for OSX library names
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@502 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 04:15:06 +00:00
Timothy Wall f1acc483c3 Disable manual WindowUtils test
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@501 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 03:49:23 +00:00
Timothy Wall 0e25e979a2 Fix window alpha compositing on X11
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@500 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 03:21:31 +00:00
Timothy Wall 0c129ff02e Fix NPE when using NativeMapped within Structure (https://jna.dev.java.net/issues/show_bug.cgi?id=54)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@499 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-28 03:15:06 +00:00
Timothy Wall 05234082a9 add rococoa
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@498 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-26 14:35:12 +00:00
Timothy Wall bdc44962a1 update javadoc for 3.0.1
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@497 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-26 14:19:37 +00:00
Timothy Wall e96a59965e add FAQ topics
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@496 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-26 14:06:05 +00:00
Timothy Wall 507f3fc74b add sunos-amd64
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@495 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-25 14:59:24 +00:00
Timothy Wall 22d997fcd9 add freebsd-amd64
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@494 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-25 14:21:59 +00:00
Timothy Wall 89a98ca51b remove obsolete comment
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@493 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-14 14:58:00 +00:00
Timothy Wall 9834abe3ab Fix X11 mappings for 64-bit
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@492 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-14 03:56:59 +00:00
Timothy Wall 54ffc2c138 enable x86_64 builds on OS X
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@491 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-11 21:06:13 +00:00
Timothy Wall 4785c4f11e finalize is more thorough than unload
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@490 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-11 21:04:47 +00:00
Timothy Wall 9d5b0deb61 Add explicit test for matching linux versioned libs
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@489 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-11 21:04:00 +00:00
Timothy Wall 9c0b540ddc Add explicit test for matching linux versioned libs
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@488 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-11 21:01:14 +00:00
Timothy Wall c124a9f2b8 Fix OSX window transparency for 1.5+/Leopard
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@487 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-08 18:18:23 +00:00
Timothy Wall 8b0e08f9df Attempt to force the VM to unload the jnidispatch native lib before deleting it (w32)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@486 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-06 13:53:02 +00:00
Timothy Wall 9ee115d1a0 allocate minimal space for invocation args, instead of MAX_NARGS
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@485 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-06 13:46:22 +00:00
Timothy Wall a7ebf431a8 fix release notes link
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@484 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 14:21:40 +00:00
Timothy Wall d85330d54a remove svn:executable from html files
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@483 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 14:21:07 +00:00
Timothy Wall f8f93c7351 Set mime type
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@482 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 14:18:16 +00:00
Timothy Wall ee1fd4944f add folder icon
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@481 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 14:15:59 +00:00
Timothy Wall 5117fa06b8 reformat release notes
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@480 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 14:15:25 +00:00
Timothy Wall 2ac1552bf7 add athena backup
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@479 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-05 13:55:10 +00:00
Timothy Wall 94c2647d25 update sunos jars
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@477 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-01 00:24:36 +00:00
Timothy Wall 6b2f067435 Ensure manifest is included in dist/jna.jar
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@476 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-02-01 00:23:44 +00:00
Timothy Wall 3e2471d0a0 Ensure tests run under appropriate VM for sparcv9
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@475 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-31 21:57:35 +00:00
Timothy Wall f0b1d33398 enable memory access protection on solaris
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@474 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-31 14:43:47 +00:00
Timothy Wall bae955f7c5 update jars to 3.0.1
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@473 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-31 02:20:34 +00:00
Timothy Wall b747e71583 clean up symbols for freebsd
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@472 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-31 00:29:59 +00:00
Timothy Wall 48160da4b7 update examples jar (WindowUtils)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@471 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-30 12:41:13 +00:00
Timothy Wall d17df6a9db Allow window masks to be set on heavyweight components (at least on w32 and x11)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@470 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-28 16:10:38 +00:00
Timothy Wall df7a9ec977 make graphics test run only if not headless
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@469 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-28 15:08:55 +00:00
Timothy Wall f2157420f2 use ffi_prep_closure_loc, not ffi_prep_closure
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@468 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-28 14:55:31 +00:00
Timothy Wall ae9c56416f Use closure alloc from libffi
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@467 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-28 14:23:23 +00:00
Timothy Wall 1dec6a541a Fix linux library name mapping (sans regexp)
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@466 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 18:04:18 +00:00
Timothy Wall c75157ffd8 Fix javadoc warnings
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@465 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 17:45:29 +00:00
Timothy Wall fa77d03fea Provide explicit dispose on NativeLibrary
Cache NativeMappedConverter instances for improved performance
Preliminary support for wince (improve backwards compatibility for older VMs)
Provide 'synch after call' interface for arguments that need to perform some sort of synchronization after a native call

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@464 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 17:33:12 +00:00
Timothy Wall 618f4c533c Fix non-w32 compilation
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@463 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 16:26:59 +00:00
Timothy Wall 9b77631dd5 update project files (netbeans/eclipse)
use setjmp/longjmp to recover from w32 faults instead of simply setting SP
embed version resource information in w32 dll
don't update last error if ffi_call faults

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@462 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 16:19:02 +00:00
Timothy Wall 7aa22df1e2 Use XImage instead of XDrawRectangle point by point
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@461 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-24 15:45:39 +00:00
Timothy Wall ee0ff79820 Fix bug in Pointer.setChar
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@460 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-23 23:03:30 +00:00
Timothy Wall ca772e8a9c add missing import
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@459 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-23 17:01:01 +00:00
Timothy Wall 8af05c14be Avoid creating too many windows when setting window mask
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@458 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-23 16:37:24 +00:00
Timothy Wall 20f230e910 fix md5 calculation on sunos
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@457 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-22 20:54:54 +00:00
Timothy Wall 8af51875b6 Improve test output
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@456 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-22 20:42:23 +00:00
Timothy Wall a4ead757f6 Fix bug in STructure.toArray w/nested struct arrays
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@455 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-22 13:56:31 +00:00
Timothy Wall 0cc6bc9e2e Improve transparent window drawing performance on w32
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@454 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-22 13:35:14 +00:00
Timothy Wall 00a551d2b1 fix html typo
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@453 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-19 22:28:02 +00:00
Timothy Wall b6f1652aab update main page
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@452 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-15 16:55:33 +00:00
Timothy Wall b304555389 Ensure initialized nested structure arrays use the right memory
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@451 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-14 19:43:41 +00:00
Timothy Wall 456af457bb Ensure initialized nested structure arrays use the right memory
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@450 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-14 19:42:08 +00:00
Timothy Wall e9cb67844d off_t size varies by platform
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@449 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2008-01-14 18:50:29 +00:00
368 arquivos alterados com 117258 adições e 78015 exclusões
+8 -8
Ver Arquivo
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="build.eclipse/test-classes" path="test"/>
<classpathentry kind="lib" path="lib/junit.jar" sourcepath="/DEV/junit/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JDK 1.5.0"/>
<classpathentry kind="output" path="build.eclipse/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="build.eclipse/test-classes" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JDK 1.5"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="output" path="build.eclipse/classes"/>
</classpath>
+21 -9
Ver Arquivo
@@ -3,14 +3,14 @@
this means no java object arguments to callbacks; use some sort of integer
key instead (hashcode?) callbacks can hold local data anyway...
o make simplest Java usage map to most common C usage
- additional constructs provided for esoteric cases (WString)
- additional constructs provided for less-common cases
(WString,Structure.ByValue/ByReference)
o structure is treated as a pointer, except within a struct
o primitive types are passed directly
o arrays are treated as pointers, except within a struct
- in structure (inline; otherwise pointer-to-X should be used)
- as function argument (auto-convert to pointer via Memory)
- pointer to type in struct should be handled with Pointer
- how to do pointer to struct in struct? (Pointer to start with)
o pointer to type in struct should use Pointer or ByReference
o "free" should be invisible wherever possible
# FUTURE DEMOS:
@@ -22,18 +22,27 @@
# 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.
o write SWIG transformer to auto-generate interfaces from header files
* stdcall/w32 underscore prefix issue
* should structure offsets be "long"?
* allow return of W/String[] or Pointer[], if NULL-terminated?
* allow return of W/String[] or Pointer[], if array is NULL-terminated?
* Direct buffers should be used where
hotspot inlining can improve performance.
* use libffi closure allocation/deallocation
* parser (gluegen? 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.
* (maybe) move all native functions into Native (limit header files, easier
management)
@@ -128,6 +137,9 @@
# DONE
* embed version in DLL ('depends'-done)/so (symlink?)
* use libffi closure allocation/deallocation
* ensure Library options are passed to NativeFunctionHandler
(needs getLibraryOptions(Class cls))
+178 -83
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,18 +28,27 @@
<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.version" value="3.0"/>
<property name="jna.major" value="3"/>
<property name="jna.minor" value="0"/>
<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.version" value="3.0"/>
<property name="jni.major" value="3"/>
<property name="jni.minor" value="0"/>
<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.version}"/>
<property name="impl.title" value="${spec.title}"/>
<property name="spec.version" value="${jna.major}"/>
<property name="impl.title" value="com.sun.jna"/>
<property name="impl.vendor" value="${spec.vendor}"/>
<property name="impl.version" value="${spec.version}"/>
<property name="impl.version" value="${jna.version} b${jna.build}"/>
<property name="compatibility" value="1.4"/>
<property name="test.compatibility" value="1.5"/>
@@ -47,10 +58,32 @@
<target name="default" depends="test" description="Build and Test."/>
<import file="nbproject/profiler-build-impl.xml"/>
<target name="init" depends="-setup"/>
<target name="compile-test-single" depends="compile-tests"/>
<target name="compile-single" depends="compile"/>
<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"/>
@@ -60,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>
@@ -73,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"/>
@@ -115,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>
@@ -147,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">
@@ -179,7 +227,15 @@
<class name="com.sun.jna.NativeLibrary"/>
<class name="com.sun.jna.CallbackReference"/>
</javah>
<apply dir="${build.native}" executable="grep" parallel="true" relative="true" output="${md5.file}">
<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}">
<arg value="-A"/>
<arg value="1"/>
<arg value="JNIEXPORT"/>
@@ -197,10 +253,14 @@
<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"/>
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-sparcv9.jar" overwrite="true"/>
<delete failOnError="false" includeEmptyDirs="true">
@@ -209,7 +269,33 @@
<fail>API for native code has changed. Re-run this build after updating jni.version and jni.md5 in build.xml</fail>
</target>
<target name="native" depends="-setup,javah,-native-api-check"
<target name=":rsrc">
<condition property="-rsrc">
<not><os family="windows"/></not>
</condition>
</target>
<target name="rsrc" depends="-setup,:rsrc" unless="-rsrc"
description="Generate w32 DLL version resource information">
<property name="rsrc" location="${build.native}/jnidispatch.rc"/>
<copy todir="${build.native}" file="${native}/jnidispatch.rc"/>
<replaceregexp match="FILEVERSION.*"
replace="FILEVERSION ${jni.major},${jni.minor},${jni.revision},${jni.build}"
file="${rsrc}" byline="true"/>
<replaceregexp match="PRODUCTVERSION.*"
replace="PRODUCTVERSION ${jna.major},${jna.minor},${jna.revision},${jna.build}"
file="${rsrc}" byline="true"/>
<replaceregexp match="FileVersion.*"
replace="FileVersion&quot;,&quot;${jni.version}&quot;"
file="${rsrc}" byline="true"/>
<replaceregexp match="Full Version.*"
replace="Full Version&quot;,&quot;${jni.version} b${jni.build}&quot;"
file="${rsrc}" byline="true"/>
<replaceregexp match="ProductVersion.*"
replace="ProductVersion&quot;,&quot;${spec.version}&quot;"
file="${rsrc}" byline="true"/>
</target>
<target name="native" depends="-setup,javah,-native-api-check,rsrc"
description="Build native libraries. Use 'ant -DCC=xxx' to build using a compiler other than gcc">
<property name="comment" value="# auto-generated by ant"/>
<replaceregexp match="^VERSION=.*"
@@ -218,14 +304,9 @@
<replaceregexp match="^CHECKSUM=.*"
replace="CHECKSUM=${jni.md5} ${comment}"
file="native/Makefile" byline="true"/>
<!-- ensure ARCH is set properly for various platforms -->
<!-- ARCH is used in native/Makefile to find the JAWT library -->
<condition property="ARCH" value="${os.arch}">
<or>
<os name="SunOS"/>
<os arch="amd64"/>
</or>
</condition>
<!-- ensure ARCH is set properly for 64-bit capable platforms -->
<!-- use ANT_OPTS=-d64 to build 64-bit if not the platform default -->
<property name="ARCH" value="${os.arch}"/>
<condition property="make.CC" value="CC=${CC}" else="IGNORE=">
<isset property="CC"/>
</condition>
@@ -235,7 +316,12 @@
<condition property="make.SDKROOT" value="SDKROOT=${SDKROOT}">
<isset property="SDKROOT"/>
</condition>
<condition property="make.SDKROOT" value="SDKROOT=/Developer/SDKs/MacOSX10.4u.sdk" else="IGNORE=">
<condition property="make.SDKROOT"
value="SDKROOT=/Developer/SDKs/MacOSX10.5.sdk">
<available file="/Developer/SDKs/MacOSX10.5.sdk"/>
</condition>
<condition property="make.SDKROOT"
value="SDKROOT=/Developer/SDKs/MacOSX10.4u.sdk" else="IGNORE=">
<available file="/Developer/SDKs/MacOSX10.4u.sdk"/>
</condition>
<!-- Windows' drive letters and spaces in absolute paths wreak havoc on
@@ -250,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"/>
@@ -259,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}"/>
@@ -269,12 +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 -->
@@ -282,7 +374,7 @@
<jar jarfile="${build}/${native.jar}">
<fileset dir="${build.native}" includes="jnidispatch.dll,libjnidispatch.*"/>
<manifest>
<attribute name="Implementation-Version" value="${jni.version}"/>
<attribute name="Implementation-Version" value="${jni.version} b${jni.build}"/>
<attribute name="Specification-Version" value="${jni.version}"/>
</manifest>
</jar>
@@ -300,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"/>
@@ -308,18 +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="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="tests.platform" value=""/>
<property name="tests.exclude" value=""/>
<junit printsummary="yes" fork="${test.fork}" failureproperty="testfailure">
<jvmarg value="-Djna.library.path=${build.native}"/>
<!-- 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}">
@@ -342,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"
@@ -362,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>
@@ -405,8 +507,19 @@
</target>
<target name="dist" depends="jar,compile-tests,native,examples,javadoc"
description="Build examples">
description="Build distribution files">
<jar jarfile="${dist}/jna.jar" duplicate="preserve">
<manifest>
<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"
includes="*jnidispatch*"
@@ -423,6 +536,9 @@
<zipfileset src="${dist}/sunos-x86.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/sunos-x86"/>
<zipfileset src="${dist}/sunos-amd64.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/sunos-amd64"/>
<zipfileset src="${dist}/sunos-sparc.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/sunos-sparc"/>
@@ -432,6 +548,15 @@
<zipfileset src="${dist}/freebsd-i386.jar"
includes="*jnidispatch*"
prefix="com/sun/jna/freebsd-i386"/>
<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}">
@@ -442,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>
@@ -460,45 +594,6 @@
</delete>
</target>
<target name="profile-single" depends="examples" description="Profile Class">
<fail unless="netbeans.home">This target can only run inside the NetBeans IDE.</fail>
<nbprofiledirect>
<classpath> <pathelement location="${build}/examples.jar"/> </classpath>
</nbprofiledirect>
<java classname="${main.class}" fork="true">
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg value="${profiler.info.jvmargs}"/>
<jvmarg value="-Djna.library.path=${build.native}"/>
<classpath>
<pathelement location="${build}/examples.jar"/>
</classpath>
</java>
</target>
<target name="profile-test-single" depends="examples,compile-tests"
description="Profile Test Class">
<fail unless="netbeans.home">This target can only run inside the NetBeans IDE.</fail>
<nbprofiledirect>
<classpath>
<pathelement location="${build}/examples.jar"/>
<pathelement location="${test.classes}"/>
</classpath>
</nbprofiledirect>
<junit dir="${build.native}" jvm="${profiler.info.jvm}"
failureproperty="tests.failed" errorproperty="tests.failed" fork="true">
<jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg value="${profiler.info.jvmargs}"/>
<jvmarg value="-Djna.library.path=${build.native}"/>
<test name="${profile.class}"/>
<classpath>
<pathelement location="${build}/examples.jar"/>
<pathelement location="${test.classes}"/>
</classpath>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
</junit>
</target>
</project>
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
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
+123 -70
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 # 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
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,87 +86,109 @@ 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')
ifeq ($(CC),cl)
LD=link
COPT=-O1 -Op
ifeq ($(DEBUG),true)
COPT=-Od
DBG=d
CDEBUG=-D_DEBUG -GZ -Zi
endif
COUT=-Fo$@
CDEFINES=-DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL -DNATIVE_EXPORTS
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
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
CDEFINES=-DHAVE_PROTECTION
WINDRES=windres
EXTRAOBJS=$(RSRC)
STRIP=@echo
else
CDEFINES=-D__int64="long long" -D_JNI_IMPLEMENTATION -DHAVE_PROTECTION
PCFLAGS+=-mno-cygwin
LDFLAGS+=-mno-cygwin -Wl,--add-stdcall-alias
LIBDIR="$(JAVA_HOME)/lib"
#LIBS=$(LIBDIR)/jawt.lib
endif
LIBPFX=
LIBSFX=.dll
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)
ifeq ($(ARCH),)
ARCH=$(shell uname -n)
ARCH=$(shell uname -p)
endif
PCFLAGS+=-fPIC
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
LD += -m64
endif
endif
ifeq ($(OS),darwin)
ARCH=$(shell arch)
ifeq ($(ARCH),ppc)
ALT_ARCH=i386
OSX_FFI_CONFIG=--host=i386-apple-darwin --disable-dependency-tracking
ALT_ARCHS=i386
else
ALT_ARCH=ppc
OSX_FFI_CONFIG=--host=powerpc-apple-darwin --disable-dependency-tracking
ALT_ARCHS=ppc
endif
FFI_ALT_BUILD=$(BUILD)/libffi-$(ALT_ARCH)
LIBSFX=.dylib
JNISFX=.jnilib
ifneq ($(SDKROOT),)
SYSLIBROOT=-Wl,-syslibroot,$(SDKROOT)
ISYSROOT=-isysroot $(SDKROOT)
ARCHFLAGS=-arch ppc -arch i386
ifneq ($(findstring 10.5,$(SDKROOT)),)
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) \
@@ -165,50 +200,68 @@ LIBS=
endif
# Unfortunately, we have to use different libffi include files depending on
# the target, so we can't do a simple universal build on darwin. Do two
# the target, so we can't do a simple universal build on darwin. Do
# separate builds, then merge the results.
$(BUILD)/%.o : %.c dispatch.h $(FFI_LIB)
@mkdir -p $(BUILD)
ifneq ($(SDKROOT),)
$(CC) -arch $(ARCH) $(CFLAGS) -c $< -o $@.$(ARCH)
$(CC) -arch $(ALT_ARCH) -I$(FFI_ALT_BUILD)/include $(CFLAGS) -c $< -o $@.$(ALT_ARCH)
lipo -create -output $@ $@.$(ARCH) $@.$(ALT_ARCH)
for arch in $(ALT_ARCHS); do \
$(CC) -arch $$arch -I$(BUILD)/libffi.$$arch/include $(CFLAGS) -c $< -o $@.$$arch; \
done
lipo -create -output $@ $@.*
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 $@ \
|| (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),)
@mkdir -p $(FFI_ALT_BUILD)
@if [ ! -f $(FFI_ALT_BUILD)/Makefile ]; then \
echo "Configuring libffi ($(ALT_ARCH))"; \
(cd $(FFI_ALT_BUILD) \
&& CFLAGS="-arch $(ALT_ARCH) $(ISYSROOT) $(COPT) $(CDEBUG) $(CDEFINES)" \
LDFLAGS="-arch $(ALT_ARCH)" \
$(FFI_SRC)/configure $(FFI_CONFIG) $(OSX_FFI_CONFIG)); \
fi
$(MAKE) -C $(FFI_ALT_BUILD)
/usr/bin/libtool -static -o $@.tmp $(FFI_BUILD)/.libs/${@F} $(FFI_ALT_BUILD)/.libs/${@F}
@mv $@.tmp $@
@for arch in $(ALT_ARCHS); do \
mkdir -p $(BUILD)/libffi.$$arch; \
if [ ! -f $(BUILD)/libffi.$$arch/Makefile ]; then \
echo "Configuring libffi ($$arch)"; \
(cd $(BUILD)/libffi.$$arch \
&& 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; \
$(MAKE) -C $(BUILD)/libffi.$$arch; \
done
/usr/bin/libtool -static -o $@.tmp $(FFI_BUILD)/.libs/${@F} $(BUILD)/libffi.*/.libs/${@F}
mv $@.tmp $@
endif
endif
clean:
@@ -217,4 +270,4 @@ clean:
version:
@echo version=$(VERSION)
#EOF
#EOF
+47 -136
Ver Arquivo
@@ -20,26 +20,9 @@
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef SLIST_ENTRY
# define MMAP_CLOSURE
# define roundup(x,y) ((((x) + ((y) - 1)) / (y)) * (y))
# define XM_ALLOC(SIZE) VirtualAlloc(0, SIZE, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
# define XM_FREE(P,SIZE) VirtualFree(P,SIZE,MEM_RELEASE)
# define PAGE_SIZE w32_page_size()
typedef void* caddr_t;
#else
# include <sys/types.h>
# include <sys/param.h>
# if defined(__linux__)
# include <sys/user.h> /* for PAGE_SIZE */
# endif
# include <sys/mman.h>
# ifdef sun
# include <sys/sysmacros.h>
# endif
# define MMAP_CLOSURE
# define XM_ALLOC(SIZE) mmap(0, SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0)
# define XM_FREE(P,SIZE) munmap(P,SIZE)
#endif
#include "dispatch.h"
@@ -48,14 +31,6 @@ extern "C" {
#endif
static void callback_dispatch(ffi_cif*, void*, void**, void*);
static ffi_closure* alloc_closure(JNIEnv *env);
static void free_closure(JNIEnv* env, ffi_closure *closure);
#ifdef MMAP_CLOSURE
#include "queue.h"
static LIST_HEAD(closure_list, list_entry) closure_list;
static LIST_HEAD(alloc_list, list_entry) alloc_list;
#endif
static jclass classObject;
@@ -66,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;
@@ -79,7 +53,7 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
}
argc = (*env)->GetArrayLength(env, param_types);
cb = (callback *)malloc(sizeof(callback));
cb->ffi_closure = alloc_closure(env);
cb->ffi_closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure);
cb->object = (*env)->NewWeakGlobalRef(env, obj);
cb->methodID = (*env)->FromReflectedMethod(env, method);
cb->vm = vm;
@@ -89,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;
}
@@ -111,51 +85,43 @@ 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(cb->ffi_closure, &cb->ffi_cif, callback_dispatch, cb);
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
free_callback(JNIEnv* env, callback *cb) {
(*env)->DeleteWeakGlobalRef(env, cb->object);
free_closure(env, cb->ffi_closure);
ffi_closure_free(cb->ffi_closure);
free(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)) {
@@ -164,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);
@@ -178,52 +147,42 @@ 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);
}
}
// Use mmap for closure memory, if available.
// A page of memory is allocated and divided into closure-sized
// chunks managed in a queue. The queue is protected by
// Java synchronization locks to ensure single-threaded access.
#ifdef MMAP_CLOSURE
# ifndef PAGE_SIZE
# if defined(PAGESIZE)
# define PAGE_SIZE PAGESIZE
# elif defined(NBPG)
# define PAGE_SIZE NBPG
# endif
# endif
typedef struct list_entry {
LIST_ENTRY(list_entry) list;
} list_entry;
#endif
#ifdef _WIN32
static int w32_page_size() {
static int page_size = 0;
if (page_size == 0) {
SYSTEM_INFO info;
GetSystemInfo(&info);
page_size = info.dwPageSize;
}
return page_size;
}
#endif
jboolean
const char*
jnidispatch_callback_init(JNIEnv* env) {
if (!LOAD_CREF(env, Object, "java/lang/Object")) return JNI_FALSE;
if (!LOAD_CREF(env, Object, "java/lang/Object")) return "java.lang.Object";
#ifdef MMAP_CLOSURE
LIST_INIT(&closure_list);
LIST_INIT(&alloc_list);
#endif
return JNI_TRUE;
return NULL;
}
void
@@ -232,54 +191,6 @@ jnidispatch_callback_dispose(JNIEnv* env) {
(*env)->DeleteWeakGlobalRef(env, classObject);
classObject = NULL;
}
#ifdef MMAP_CLOSURE
while (alloc_list.lh_first != NULL) {
list_entry* entry = alloc_list.lh_first;
XM_FREE((caddr_t)entry, PAGE_SIZE);
LIST_REMOVE(entry, list);
}
#endif
}
static ffi_closure*
alloc_closure(JNIEnv* env) {
#ifdef MMAP_CLOSURE
list_entry* entry = NULL;
if (closure_list.lh_first == NULL) {
/*
* Get a new page from the kernel and divvy that up
*/
int clsize = roundup(sizeof(ffi_closure), sizeof(list_entry));
int i;
caddr_t ptr = XM_ALLOC(PAGE_SIZE);
if (ptr == NULL) {
return NULL;
}
LIST_INSERT_HEAD(&alloc_list, (list_entry*)ptr, list);
for (i = 0; i <= (int)(PAGE_SIZE - clsize); i += clsize) {
entry = (list_entry *)(ptr + i);
LIST_INSERT_HEAD(&closure_list, entry, list);
}
}
entry = closure_list.lh_first;
LIST_REMOVE(entry, list);
memset(entry, 0, sizeof(ffi_closure));
return (ffi_closure *)entry;
#else
return (ffi_closure *)calloc(1, sizeof(ffi_closure));
#endif
}
static void
free_closure(JNIEnv* env, ffi_closure *ffi_closure) {
#ifdef MMAP_CLOSURE
LIST_INSERT_HEAD(&closure_list, (list_entry*)ffi_closure, list);
#else
free(closure);
#endif
}
#ifdef __cplusplus
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
+195 -119
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,17 +49,21 @@
#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
#include <dlfcn.h>
#include <errno.h>
#define LIBNAMETYPE char*
#ifdef __APPLE__
#define LIBNAME2CSTR(ENV,JSTR) newCStringUTF8(ENV,JSTR)
#else
#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
@@ -77,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"
@@ -87,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)
@@ -127,6 +138,7 @@ static jclass classStructureByValue;
static jmethodID MID_Class_getComponentType;
static jmethodID MID_String_getBytes;
static jmethodID MID_String_getBytes2;
static jmethodID MID_String_toCharArray;
static jmethodID MID_String_init_bytes;
static jmethodID MID_Method_getReturnType;
@@ -174,6 +186,7 @@ static jfieldID FID_Structure_typeInfo;
/* Forward declarations */
static char* newCString(JNIEnv *env, jstring jstr);
static char* newCStringUTF8(JNIEnv *env, jstring jstr);
static wchar_t* newWideCString(JNIEnv *env, jstring jstr);
static jstring newJavaString(JNIEnv *env, const char *str, jboolean wide);
@@ -185,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");
@@ -205,17 +219,17 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
{
int i, nargs;
void *func;
jvalue c_args[MAX_NARGS];
jvalue* c_args;
char array_pt;
struct _array_elements {
char type;
jobject array;
void *elems;
} array_elements[MAX_NARGS];
} *array_elements;
int array_count = 0;
ffi_cif cif;
ffi_type* ffi_types[MAX_NARGS];
void* ffi_values[MAX_NARGS];
ffi_type** ffi_types;
void** ffi_values;
ffi_abi abi;
ffi_status status;
char msg[128];
@@ -223,10 +237,16 @@ 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));
ffi_types = (ffi_type**)alloca(nargs * sizeof(ffi_type*));
ffi_values = (void**)alloca(nargs * sizeof(void*));
// Get the function pointer
func = getNativeAddress(env, self);
@@ -266,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;
}
@@ -301,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;
}
@@ -311,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;
@@ -350,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;
}
@@ -360,37 +380,47 @@ 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: {
PSTART();
ffi_call(&cif, FFI_FN(func), resP, ffi_values);
PEND();
if (preserve_last_error) {
update_last_error(env, GET_LAST_ERROR());
}
PEND();
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;
}
@@ -657,122 +687,125 @@ Java_com_sun_jna_NativeLibrary_findSymbol(JNIEnv *env, jclass cls,
return (jlong)A2L(func);
}
static jboolean
static const char*
jnidispatch_init(JNIEnv* env) {
if (!LOAD_CREF(env, Object, "java/lang/Object")) return JNI_FALSE;
if (!LOAD_CREF(env, Class, "java/lang/Class")) return JNI_FALSE;
if (!LOAD_CREF(env, Method, "java/lang/reflect/Method")) return JNI_FALSE;
if (!LOAD_CREF(env, String, "java/lang/String")) return JNI_FALSE;
if (!LOAD_CREF(env, Buffer, "java/nio/Buffer")) return JNI_FALSE;
if (!LOAD_CREF(env, ByteBuffer, "java/nio/ByteBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, CharBuffer, "java/nio/CharBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, ShortBuffer, "java/nio/ShortBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, IntBuffer, "java/nio/IntBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, LongBuffer, "java/nio/LongBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, FloatBuffer, "java/nio/FloatBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, DoubleBuffer, "java/nio/DoubleBuffer")) return JNI_FALSE;
if (!LOAD_CREF(env, Object, "java/lang/Object")) return "java.lang.Object";
if (!LOAD_CREF(env, Class, "java/lang/Class")) return "java.lang.Class";
if (!LOAD_CREF(env, Method, "java/lang/reflect/Method")) return "java.lang.reflect.Method";
if (!LOAD_CREF(env, String, "java/lang/String")) return "java.lang.String";
if (!LOAD_CREF(env, Buffer, "java/nio/Buffer")) return "java.nio.Buffer";
if (!LOAD_CREF(env, ByteBuffer, "java/nio/ByteBuffer")) return "java.nio.ByteBuffer";
if (!LOAD_CREF(env, CharBuffer, "java/nio/CharBuffer")) return "java.nio.CharBuffer";
if (!LOAD_CREF(env, ShortBuffer, "java/nio/ShortBuffer")) return "java.nio.ShortBuffer";
if (!LOAD_CREF(env, IntBuffer, "java/nio/IntBuffer")) return "java.nio.IntBuffer";
if (!LOAD_CREF(env, LongBuffer, "java/nio/LongBuffer")) return "java.nio.LongBuffer";
if (!LOAD_CREF(env, FloatBuffer, "java/nio/FloatBuffer")) return "java.nio.FloatBuffer";
if (!LOAD_CREF(env, DoubleBuffer, "java/nio/DoubleBuffer")) return "java.nio.DoubleBuffer";
if (!LOAD_PCREF(env, Void, "java/lang/Void")) return JNI_FALSE;
if (!LOAD_PCREF(env, Boolean, "java/lang/Boolean")) return JNI_FALSE;
if (!LOAD_PCREF(env, Byte, "java/lang/Byte")) return JNI_FALSE;
if (!LOAD_PCREF(env, Character, "java/lang/Character")) return JNI_FALSE;
if (!LOAD_PCREF(env, Short, "java/lang/Short")) return JNI_FALSE;
if (!LOAD_PCREF(env, Integer, "java/lang/Integer")) return JNI_FALSE;
if (!LOAD_PCREF(env, Long, "java/lang/Long")) return JNI_FALSE;
if (!LOAD_PCREF(env, Float, "java/lang/Float")) return JNI_FALSE;
if (!LOAD_PCREF(env, Double, "java/lang/Double")) return JNI_FALSE;
if (!LOAD_PCREF(env, Void, "java/lang/Void")) return "java.lang.Void";
if (!LOAD_PCREF(env, Boolean, "java/lang/Boolean")) return "java.lang.Boolean";
if (!LOAD_PCREF(env, Byte, "java/lang/Byte")) return "java.lang.Byte";
if (!LOAD_PCREF(env, Character, "java/lang/Character")) return "java.lang.Character";
if (!LOAD_PCREF(env, Short, "java/lang/Short")) return "java.lang.Short";
if (!LOAD_PCREF(env, Integer, "java/lang/Integer")) return "java.lang.Integer";
if (!LOAD_PCREF(env, Long, "java/lang/Long")) return "java.lang.Long";
if (!LOAD_PCREF(env, Float, "java/lang/Float")) return "java.lang.Float";
if (!LOAD_PCREF(env, Double, "java/lang/Double")) return "java.lang.Double";
if (!LOAD_MID(env, MID_Long_init, classLong,
"<init>", "(J)V"))
return JNI_FALSE;
return "java.lang.Long<init>(J)V";
if (!LOAD_MID(env, MID_Integer_init, classInteger,
"<init>", "(I)V"))
return JNI_FALSE;
return "java.lang.Integer<init>(I)V";
if (!LOAD_MID(env, MID_Short_init, classShort,
"<init>", "(S)V"))
return JNI_FALSE;
return "java.lang.Short<init>(S)V";
if (!LOAD_MID(env, MID_Character_init, classCharacter,
"<init>", "(C)V"))
return JNI_FALSE;
return "java.lang.Character<init>(C)V";
if (!LOAD_MID(env, MID_Byte_init, classByte,
"<init>", "(B)V"))
return JNI_FALSE;
return "java.lang.Byte<init>(B)V";
if (!LOAD_MID(env, MID_Boolean_init, classBoolean,
"<init>", "(Z)V"))
return JNI_FALSE;
return "java.lang.Boolean<init>(Z)V";
if (!LOAD_MID(env, MID_Float_init, classFloat,
"<init>", "(F)V"))
return JNI_FALSE;
return "java.lang.Float<init>(F)V";
if (!LOAD_MID(env, MID_Double_init, classDouble,
"<init>", "(D)V"))
return JNI_FALSE;
return "java.lang.Double<init>(D)V";
if (!LOAD_MID(env, MID_Class_getComponentType, classClass,
"getComponentType", "()Ljava/lang/Class;"))
return JNI_FALSE;
return "Class.getComponentType(Class)";
if (!LOAD_MID(env, MID_String_getBytes, classString,
"getBytes", "()[B"))
return JNI_FALSE;
return "String.getBytes()";
if (!LOAD_MID(env, MID_String_getBytes2, classString,
"getBytes", "(Ljava/lang/String;)[B"))
return "String.getBytes(String)";
if (!LOAD_MID(env, MID_String_toCharArray, classString,
"toCharArray", "()[C"))
return JNI_FALSE;
return "String.toCharArray()";
if (!LOAD_MID(env, MID_String_init_bytes, classString,
"<init>", "([B)V"))
return JNI_FALSE;
return "String<init>([B)V";
if (!LOAD_MID(env, MID_Method_getParameterTypes, classMethod,
"getParameterTypes", "()[Ljava/lang/Class;"))
return JNI_FALSE;
return "Method.getParameterTypes()";
if (!LOAD_MID(env, MID_Method_getReturnType, classMethod,
"getReturnType", "()Ljava/lang/Class;"))
return JNI_FALSE;
return "Method.getReturnType()";
if (!LOAD_MID(env, MID_ByteBuffer_array, classByteBuffer, "array", "()[B"))
return JNI_FALSE;
return "ByteBuffer.array";
if (!LOAD_MID(env, MID_ByteBuffer_arrayOffset, classByteBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "ByteBuffer.arrayOffset";
if (!LOAD_MID(env, MID_CharBuffer_array, classCharBuffer, "array", "()[C"))
return JNI_FALSE;
return "CharBuffer.array";
if (!LOAD_MID(env, MID_CharBuffer_arrayOffset, classCharBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "CharBuffer.arrayOffset";
if (!LOAD_MID(env, MID_ShortBuffer_array, classShortBuffer, "array", "()[S"))
return JNI_FALSE;
return "ShortBuffer.array";
if (!LOAD_MID(env, MID_ShortBuffer_arrayOffset, classShortBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "ShortBuffer.arrayOffset";
if (!LOAD_MID(env, MID_IntBuffer_array, classIntBuffer, "array", "()[I"))
return JNI_FALSE;
return "IntBuffer.array";
if (!LOAD_MID(env, MID_IntBuffer_arrayOffset, classIntBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "IntBuffer.arrayOffset";
if (!LOAD_MID(env, MID_LongBuffer_array, classLongBuffer, "array", "()[J"))
return JNI_FALSE;
return "LongBuffer.array";
if (!LOAD_MID(env, MID_LongBuffer_arrayOffset, classLongBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "LongBuffer.arrayOffset";
if (!LOAD_MID(env, MID_FloatBuffer_array, classFloatBuffer, "array", "()[F"))
return JNI_FALSE;
return "FloatBuffer.array";
if (!LOAD_MID(env, MID_FloatBuffer_arrayOffset, classFloatBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "FloatBuffer.arrayOffset";
if (!LOAD_MID(env, MID_DoubleBuffer_array, classDoubleBuffer, "array", "()[D"))
return JNI_FALSE;
return "DoubleBuffer.array";
if (!LOAD_MID(env, MID_DoubleBuffer_arrayOffset, classDoubleBuffer, "arrayOffset", "()I"))
return JNI_FALSE;
return "DoubleBuffer.arrayOffset";
if (!LOAD_FID(env, FID_Boolean_value, classBoolean, "value", "Z"))
return JNI_FALSE;
return "Boolean.value";
if (!LOAD_FID(env, FID_Byte_value, classByte, "value", "B"))
return JNI_FALSE;
return "Byte.value";
if (!LOAD_FID(env, FID_Short_value, classShort, "value", "S"))
return JNI_FALSE;
return "Short.value";
if (!LOAD_FID(env, FID_Character_value, classCharacter, "value", "C"))
return JNI_FALSE;
return "Character.value";
if (!LOAD_FID(env, FID_Integer_value, classInteger, "value", "I"))
return JNI_FALSE;
return "Integer.value";
if (!LOAD_FID(env, FID_Long_value, classLong, "value", "J"))
return JNI_FALSE;
return "Long.value";
if (!LOAD_FID(env, FID_Float_value, classFloat, "value", "F"))
return JNI_FALSE;
return "Float.value";
if (!LOAD_FID(env, FID_Double_value, classDouble, "value", "D"))
return JNI_FALSE;
return "Double.value";
return JNI_TRUE;
return NULL;
}
/*
@@ -983,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;
}
@@ -996,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;
}
@@ -1009,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);
}
@@ -1033,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;
}
@@ -1046,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;
}
@@ -1059,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;
}
@@ -1072,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;
}
@@ -1085,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;
}
@@ -1131,7 +1164,8 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Pointer__1setByte
JNIEXPORT void JNICALL Java_com_sun_jna_Pointer__1setChar
(JNIEnv *env, jclass cls, jlong addr, jchar value)
{
MEMCPY(L2A(addr), &value, sizeof(value));
wchar_t ch = value;
MEMCPY(L2A(addr), &ch, sizeof(ch));
}
/*
@@ -1292,6 +1326,32 @@ newCString(JNIEnv *env, jstring jstr)
return result;
}
/* Translates a Java string to a C string using the String.getBytes("UTF8")
* method, which uses UTF8 encoding.
*/
static char *
newCStringUTF8(JNIEnv *env, jstring jstr)
{
jbyteArray bytes = 0;
char *result = NULL;
bytes = (*env)->CallObjectMethod(env, jstr, MID_String_getBytes2,
newJavaString(env, "UTF8", JNI_FALSE));
if (!(*env)->ExceptionCheck(env)) {
jint len = (*env)->GetArrayLength(env, bytes);
result = (char *)malloc(len + 1);
if (result == NULL) {
throwByName(env, EOutOfMemory, "Can't allocate C string");
(*env)->DeleteLocalRef(env, bytes);
return NULL;
}
(*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *)result);
result[len] = 0; /* NUL-terminate */
}
(*env)->DeleteLocalRef(env, bytes);
return result;
}
/* Translates a Java string to a wide C string using the String.toCharArray
* method.
*/
@@ -1307,7 +1367,7 @@ newWideCString(JNIEnv *env, jstring str)
jint len = (*env)->GetArrayLength(env, chars);
result = (wchar_t *)malloc(sizeof(wchar_t) * (len + 1));
if (result == NULL) {
throwByName(env, EOutOfMemory, 0);
throwByName(env, EOutOfMemory, "Can't allocate wide C string");
(*env)->DeleteLocalRef(env, chars);
return NULL;
}
@@ -1338,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;
@@ -1353,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) {
@@ -1493,6 +1553,7 @@ do { jboolean cpy; \
*elemp = ptr;
ptr = (char *)ptr + offset;
}
return ptr;
}
@@ -1611,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);
@@ -1626,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
@@ -1673,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];
@@ -1691,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;
@@ -1727,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");
}
@@ -1787,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;
@@ -1913,6 +1983,8 @@ JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv* env;
int result = JNI_VERSION_1_4;
int attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
const char* err;
if (!attached) {
if ((*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL) != JNI_OK) {
fprintf(stderr, "JNA: Can't attach to JVM thread on load\n");
@@ -1920,8 +1992,12 @@ JNI_OnLoad(JavaVM *jvm, void *reserved) {
}
}
if (!jnidispatch_init(env)
|| !jnidispatch_callback_init(env)) {
if ((err = jnidispatch_init(env)) != NULL) {
fprintf(stderr, "JNA: Problems loading core IDs: %s\n", err);
result = 0;
}
else if ((err = jnidispatch_callback_init(env)) != NULL) {
fprintf(stderr, "JNA: Problems loading callback IDs: %s\n", err);
result = 0;
}
@@ -2035,7 +2111,7 @@ get_ffi_rtype(JNIEnv* env, jclass cls, char jtype) {
return get_ffi_type(env, cls, jtype);
}
}
#ifdef __cplusplus
}
#endif
+21 -2
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;
@@ -32,6 +32,8 @@ typedef enum _callconv {
#define MAX_NARGS com_sun_jna_Function_MAX_NARGS
typedef struct _callback {
// Location of this field must agree with CallbackReference.getTrampoline()
void* x_closure;
ffi_closure* ffi_closure;
ffi_cif ffi_cif;
ffi_type* ffi_args[MAX_NARGS];
@@ -45,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 */
@@ -86,7 +94,7 @@ extern jobject newJavaPointer(JNIEnv *, void *);
extern char get_jtype(JNIEnv*, jclass);
extern ffi_type* get_ffi_type(JNIEnv*, jclass, char);
extern ffi_type* get_ffi_rtype(JNIEnv*, jclass, char);
extern jboolean jnidispatch_callback_init(JNIEnv*);
extern const char* jnidispatch_callback_init(JNIEnv*);
extern void jnidispatch_callback_dispose(JNIEnv*);
extern callback* create_callback(JNIEnv*, jobject, jobject,
jobjectArray, jclass,
@@ -94,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
+34
Ver Arquivo
@@ -0,0 +1,34 @@
// Resource file to generate version information for jnidispatch.dll
// Copyright (c) 2008 Timothy Wall
// Type: version
// Name: 1
LANGUAGE 0, 0
1 VERSIONINFO
FILEVERSION 3,0,0,0
PRODUCTVERSION 3,0,1,0
FILEFLAGSMASK 0x3f
FILEOS 0x4
FILETYPE 0x2
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "Java(TM) Native Access (JNA)"
VALUE "FileDescription", "JNA native library"
VALUE "FileVersion","3.0.0"
VALUE "Full Version","3.0.0 b0"
VALUE "InternalName", "jnidispatch"
VALUE "LegalCopyright", "Copyright \251 2008 Timothy Wall"
VALUE "OriginalFilename", "jnidispatch.dll"
VALUE "ProductName", "Java(TM) Native Access"
VALUE "ProductVersion","3"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
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@
+53 -28
Ver Arquivo
@@ -32,7 +32,7 @@
//
// The PROTECT_START() macro must immediately follow any variable declarations
//
// The w32 implementation is courtesy of Ranjit Mathew
// The w32 implementation is based on code by Ranjit Mathew
// http://gcc.gnu.org/ml/java/2003-03/msg00243.html
#ifndef PROTECT
@@ -41,64 +41,89 @@
#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 {
EXCEPTION_REGISTRATION ex_reg;
void* exc_handling_addr;
jmp_buf buf;
struct _EXCEPTION_RECORD er;
} exc_rec;
static EXCEPTION_DISPOSITION __cdecl
exc_handler(struct _EXCEPTION_RECORD* exception_record,
void *establisher_frame,
struct _CONTEXT *context_record,
void* dispatcher_context) {
_exc_handler(struct _EXCEPTION_RECORD* exception_record,
void *establisher_frame,
struct _CONTEXT *context_record,
void* dispatcher_context) {
exc_rec* xer = (exc_rec *)establisher_frame;
/* Unwind from the called function assuming the standard
* function prologue.
*/
context_record->Esp = context_record->Ebp;
context_record->Ebp = *((DWORD *)context_record->Esp);
context_record->Esp = context_record->Esp - 8;
/* Restart execution at the handler within the caller */
context_record->Eip = (DWORD )(xer->exc_handling_addr);
/* Tell Windows to restart the "faulting" instruction. */
xer->er = *exception_record;
longjmp(xer->buf, exception_record->ExceptionCode);
// Never reached
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; \
exc_rec _er; \
int _error = 0; \
if (PROTECT) { \
er.exc_handling_addr = &&_exc_caught; \
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)); \
_er.ex_reg.handler = _exc_handler; \
SEH_TRY(_er); \
if ((_error = setjmp(_er.buf)) != 0) { \
goto _exc_caught; \
} \
}
// The initial conditional is required to ensure GCC doesn't consider
// _exc_caught to be unreachable
#define PROTECTED_END(ONERR) do { \
if (!PROTECT || er.exc_handling_addr != 0) \
if (!_error) \
goto _remove_handler; \
_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
#include <signal.h>
#include <setjmp.h>
static jmp_buf context;
static jmp_buf _context;
static volatile int _error;
static void _exc_handler(int sig) {
if (sig == SIGSEGV || sig == SIGBUS) {
longjmp(context, sig);
longjmp(_context, sig);
}
}
@@ -109,7 +134,7 @@ static void _exc_handler(int sig) {
if (PROTECT) { \
_old_segv_handler = signal(SIGSEGV, _exc_handler); \
_old_bus_handler = signal(SIGBUS, _exc_handler); \
if ((_error = setjmp(context) != 0)) { \
if ((_error = setjmp(_context) != 0)) { \
goto _exc_caught; \
} \
}
-568
Ver Arquivo
@@ -1,568 +0,0 @@
/*
* 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.
*/
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
* A singly-linked list is headed by a single forward pointer. The
* elements are singly linked for minimum space and pointer manipulation
* overhead at the expense of O(n) removal for arbitrary elements. New
* elements can be added to the list after an existing element or at the
* head of the list. Elements being removed from the head of the list
* should use the explicit macro for this purpose for optimum
* efficiency. A singly-linked list may only be traversed in the forward
* direction. Singly-linked lists are ideal for applications with large
* datasets and few or no removals or for implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (/*CONSTCOND*/0)
#define LIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) do { \
(head)->slh_first = NULL; \
} while (/*CONSTCOND*/0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (/*CONSTCOND*/0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (/*CONSTCOND*/0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (/*CONSTCOND*/0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while(curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (/*CONSTCOND*/0)
#define SLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
/*
* Singly-linked List access methods.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first; /* first element */ \
struct type **stqh_last; /* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_INIT(head) do { \
(head)->stqh_first = NULL; \
(head)->stqh_last = &(head)->stqh_first; \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
(head)->stqh_last = &(elm)->field.stqe_next; \
(head)->stqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.stqe_next = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &(elm)->field.stqe_next; \
} while (/*CONSTCOND*/0)
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
(head)->stqh_last = &(elm)->field.stqe_next; \
(listelm)->field.stqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (/*CONSTCOND*/0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if ((head)->stqh_first == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->stqh_first; \
while (curelm->field.stqe_next != (elm)) \
curelm = curelm->field.stqe_next; \
if ((curelm->field.stqe_next = \
curelm->field.stqe_next->field.stqe_next) == NULL) \
(head)->stqh_last = &(curelm)->field.stqe_next; \
} \
} while (/*CONSTCOND*/0)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->stqh_first); \
(var); \
(var) = ((var)->field.stqe_next))
/*
* Singly-linked Tail queue access methods.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
SIMPLEQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \
if ((curelm->field.sqe_next = \
curelm->field.sqe_next->field.sqe_next) == NULL) \
(head)->sqh_last = &(curelm)->field.sqe_next; \
} \
} while (/*CONSTCOND*/0)
#define SIMPLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->sqh_first); \
(var); \
(var) = ((var)->field.sqe_next))
/*
* Simple queue access methods.
*/
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
/*
* Tail queue definitions.
*/
#define _TAILQ_HEAD(name, type, qual) \
struct name { \
qual type *tqh_first; /* first element */ \
qual type *qual *tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define _TAILQ_ENTRY(type, qual) \
struct { \
qual type *tqe_next; /* next element */ \
qual type *qual *tqe_prev; /* address of previous next element */\
}
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->tqh_first); \
(var); \
(var) = ((var)->field.tqe_next))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
(var); \
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
/*
* Tail queue access methods.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ (void *)&head, (void *)&head }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = (void *)(head); \
(head)->cqh_last = (void *)(head); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = (void *)(head); \
if ((head)->cqh_last == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = (void *)(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
} while (/*CONSTCOND*/0)
#define CIRCLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->cqh_first); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_next))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for ((var) = ((head)->cqh_last); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_prev))
/*
* Circular queue access methods.
*/
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
(((elm)->field.cqe_next == (void *)(head)) \
? ((head)->cqh_first) \
: (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
(((elm)->field.cqe_prev == (void *)(head)) \
? ((head)->cqh_last) \
: (elm->field.cqe_prev))
#endif /* sys/queue.h */
+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
+258 -172
Ver Arquivo
@@ -18,32 +18,35 @@ is divided into following sections:
- applet
- cleanup
-->
<project name="JNA_Library-impl" default="default" basedir=".." xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:j2seproject2="http://www.netbeans.org/ns/j2se-project/2" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:jaxws="http://www.netbeans.org/ns/jax-ws/1">
<target name="default" depends="test,jar,javadoc" description="Build and test whole project."/>
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject2="http://www.netbeans.org/ns/j2se-project/2" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="JNA_Library-impl">
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-init-private" depends="-pre-init">
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target name="-init-user" depends="-pre-init,-init-private">
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
</target>
<target name="-init-project" depends="-pre-init,-init-private,-init-user">
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target name="-do-init" depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property">
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<condition property="manifest.available+main.class">
<and>
@@ -77,7 +80,10 @@ is divided into following sections:
</and>
</condition>
<condition property="no.javadoc.preview">
<isfalse value="${javadoc.preview}"/>
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
@@ -89,12 +95,35 @@ is divided into following sections:
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
<and>
<isset property="jaxws.endorsed.dir"/>
<available file="nbproject/jaxws-build.xml"/>
</and>
</condition>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-init-check" depends="-pre-init,-init-private,-init-user,-init-project,-do-init">
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="test.src.dir">Must set test.src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
@@ -117,36 +146,70 @@ is divided into following sections:
</target>
<target name="-init-macrodef-javac">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute name="srcdir" default="${src.dir}"/>
<attribute name="destdir" default="${build.classes.dir}"/>
<attribute name="classpath" default="${javac.classpath}"/>
<attribute name="debug" default="${javac.debug}"/>
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="" name="sourcepath"/>
<element name="customize" optional="true"/>
<sequential>
<javac srcdir="@{srcdir}" destdir="@{destdir}" debug="@{debug}" deprecation="${javac.deprecation}" source="${javac.source}" target="${javac.target}" includeantruntime="false">
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${javac.compilerargs}"/>
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
<customize/>
</javac>
</sequential>
</macrodef>
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="," property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<delete>
<files includes="${javac.includes.binary}"/>
</delete>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute name="includes" default="**/*Test.java"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit showoutput="true" fork="true" dir="${basedir}" failureproperty="tests.failed" errorproperty="tests.failed">
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
<batchtest todir="${build.test.results.dir}">
<fileset dir="${test.src.dir}" includes="@{includes}"/>
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
<filename name="@{testincludes}"/>
</fileset>
</batchtest>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper type="glob" from="test-sys-prop.*" to="*"/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
@@ -157,11 +220,11 @@ is divided into following sections:
</target>
<target name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name" default="${main.class}"/>
<attribute name="classpath" default="${debug.classpath}"/>
<attribute name="stopclassname" default=""/>
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart transport="dt_socket" addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}">
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="dt_socket">
<classpath>
<path path="@{classpath}"/>
</classpath>
@@ -169,24 +232,36 @@ is divided into following sections:
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="dir" default="${build.classes.dir}"/>
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset includes="${fix.includes}*.class" dir="@{dir}"/>
<fileset dir="@{dir}" includes="${fix.includes}*.class"/>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-debug">
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute name="classname" default="${main.class}"/>
<attribute name="classpath" default="${debug.classpath}"/>
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java fork="true" classname="@{classname}" dir="${work.dir}">
<jvmarg value="-Xdebug"/>
<jvmarg value="-Xnoagent"/>
<jvmarg value="-Djava.compiler=none"/>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
@@ -194,7 +269,7 @@ is divided into following sections:
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper type="glob" from="run-sys-prop.*" to="*"/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
@@ -203,17 +278,17 @@ is divided into following sections:
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="classname" default="${main.class}"/>
<attribute default="${main.class}" name="classname"/>
<element name="customize" optional="true"/>
<sequential>
<java fork="true" classname="@{classname}" dir="${work.dir}">
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="${run.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper type="glob" from="run-sys-prop.*" to="*"/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
@@ -222,102 +297,102 @@ is divided into following sections:
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar jarfile="${dist.jar}" compress="${jar.compress}">
<jar compress="${jar.compress}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target name="init" depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar"/>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target name="deps-jar" depends="init" unless="no.deps"/>
<target name="-pre-pre-compile" depends="init,deps-jar">
===================
COMPILATION SECTION
===================
-->
<target depends="init" name="deps-jar" unless="no.deps"/>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-do-compile" depends="init,deps-jar,-pre-pre-compile,-pre-compile" if="have.sources">
<target if="do.depend.true" name="-compile-depend">
<j2seproject3:depend/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes}"/>
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="compile" depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project."/>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-do-compile-single" depends="init,deps-jar,-pre-pre-compile">
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:javac>
<customize>
<patternset includes="${javac.includes}"/>
</customize>
</j2seproject3:javac>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="compile-single" depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single"/>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target name="-pre-pre-jar" depends="init">
<dirname property="dist.jar.dir" file="${dist.jar}"/>
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-do-jar-without-manifest" depends="init,compile,-pre-pre-jar,-pre-jar" unless="manifest.available">
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target name="-do-jar-with-manifest" depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" unless="manifest.available+main.class">
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target name="-do-jar-with-mainclass" depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" unless="manifest.available+main.class+mkdist.available">
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property name="build.classes.dir.resolved" location="${build.classes.dir}"/>
<property name="dist.jar.resolved" location="${dist.jar}"/>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target name="-do-jar-with-libraries" depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available">
<property name="build.classes.dir.resolved" location="${build.classes.dir}"/>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert property="jar.classpath" pathsep=" ">
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" name="copylibs" classpath="${libs.CopyLibs.classpath}"/>
<copylibs manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}" jarfile="${dist.jar}" compress="${jar.compress}">
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
@@ -325,183 +400,194 @@ is divided into following sections:
</manifest>
</copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property name="dist.jar.resolved" location="${dist.jar}"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="jar" depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR."/>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target name="run" depends="init,compile" description="Run a main class.">
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="run-single" depends="init,compile-single">
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,-do-not-recompile,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target name="-debug-start-debugger" if="netbeans.home" depends="init">
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target name="-debug-start-debuggee" depends="init,compile">
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target name="debug" if="netbeans.home" depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE."/>
<target name="-debug-start-debugger-stepinto" if="netbeans.home" depends="init">
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target name="debug-stepinto" if="netbeans.home" depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee"/>
<target name="-debug-start-debuggee-single" if="netbeans.home" depends="init,compile-single">
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target name="debug-single" if="netbeans.home" depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single"/>
<target name="-pre-debug-fix" depends="init">
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target name="-do-debug-fix" if="netbeans.home" depends="init,-pre-debug-fix,compile-single">
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target name="debug-fix" if="netbeans.home" depends="init,-pre-debug-fix,-do-debug-fix"/>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target name="-javadoc-build" depends="init">
===============
JAVADOC SECTION
===============
-->
<target depends="init" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc destdir="${dist.javadoc.dir}" source="${javac.source}" notree="${javadoc.notree}" use="${javadoc.use}" nonavbar="${javadoc.nonavbar}" noindex="${javadoc.noindex}" splitindex="${javadoc.splitindex}" author="${javadoc.author}" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}" private="${javadoc.private}" additionalparam="${javadoc.additionalparam}" failonerror="true" useexternalfile="true">
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<sourcepath>
<pathelement location="${src.dir}"/>
</sourcepath>
<packageset dir="${src.dir}" includes="*/**"/>
<fileset dir="${src.dir}" includes="*.java"/>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
</javadoc>
</target>
<target name="-javadoc-browse" if="netbeans.home" unless="no.javadoc.preview" depends="init,-javadoc-build">
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target name="javadoc" depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc."/>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target name="-pre-pre-compile-test" if="have.tests" depends="init,compile">
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-do-compile-test" if="have.tests" depends="init,compile,-pre-pre-compile-test,-pre-compile-test">
<j2seproject3:javac srcdir="${test.src.dir}" destdir="${build.test.classes.dir}" debug="true" classpath="${javac.test.classpath}"/>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="**/*.java"/>
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="compile-test" depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test"/>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="-do-compile-test-single" if="have.tests" depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single">
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:javac srcdir="${test.src.dir}" destdir="${build.test.classes.dir}" debug="true" classpath="${javac.test.classpath}">
<customize>
<patternset includes="${javac.includes}"/>
</customize>
</j2seproject3:javac>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="**/*.java"/>
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="compile-test-single" depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single"/>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target name="-pre-test-run" if="have.tests" depends="init">
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target name="-do-test-run" if="have.tests" depends="init,compile-test,-pre-test-run">
<j2seproject3:junit/>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target name="-post-test-run" if="have.tests" depends="init,compile-test,-pre-test-run,-do-test-run">
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed">Some tests failed; see details above.</fail>
</target>
<target name="test-report" if="have.tests" depends="init"/>
<target name="-test-browse" if="netbeans.home+have.tests" depends="init"/>
<target name="test" depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests."/>
<target name="-pre-test-run-single" if="have.tests" depends="init">
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target name="-do-test-run-single" if="have.tests" depends="init,compile-test-single,-pre-test-run-single">
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit includes="${test.includes}"/>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target name="-post-test-run-single" if="have.tests" depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single">
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed">Some tests failed; see details above.</fail>
</target>
<target name="test-single" depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test."/>
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target name="-debug-start-debuggee-test" if="have.tests" depends="init,compile-test">
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<j2seproject3:debug classname="junit.textui.TestRunner" classpath="${debug.test.classpath}">
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<arg line="${test.class}"/>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target name="-debug-start-debugger-test" if="netbeans.home+have.tests" depends="init,compile-test">
<j2seproject1:nbjpdastart name="${test.class}" classpath="${debug.test.classpath}"/>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target name="debug-test" depends="init,compile-test,-debug-start-debugger-test,-debug-start-debuggee-test"/>
<target name="-do-debug-fix-test" if="netbeans.home" depends="init,-pre-debug-fix,compile-test-single">
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target name="debug-fix-test" if="netbeans.home" depends="init,-pre-debug-fix,-do-debug-fix-test"/>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target name="run-applet" depends="init,compile-single">
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
@@ -510,11 +596,11 @@ is divided into following sections:
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target name="-debug-start-debuggee-applet" if="netbeans.home" depends="init,compile-single">
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
@@ -522,14 +608,14 @@ is divided into following sections:
</customize>
</j2seproject3:debug>
</target>
<target name="debug-applet" if="netbeans.home" depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet"/>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target name="deps-clean" depends="init" unless="no.deps"/>
<target name="-do-clean" depends="init">
===============
CLEANUP SECTION
===============
-->
<target depends="init" name="deps-clean" unless="no.deps"/>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
@@ -537,5 +623,5 @@ is divided into following sections:
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target name="clean" depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products."/>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
</project>
+3 -3
Ver Arquivo
@@ -2,8 +2,8 @@ build.xml.data.CRC32=c09e9b0e
build.xml.script.CRC32=6f0d9f8d
build.xml.stylesheet.CRC32=240b97a2
nbproject/build-impl.xml.data.CRC32=c09e9b0e
nbproject/build-impl.xml.script.CRC32=216dd50e
nbproject/build-impl.xml.stylesheet.CRC32=20b9345e
nbproject/build-impl.xml.script.CRC32=ee8cb023
nbproject/build-impl.xml.stylesheet.CRC32=f1d9da08
nbproject/profiler-build-impl.xml.data.CRC32=c09e9b0e
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
nbproject/profiler-build-impl.xml.stylesheet.CRC32=a5b6598e
nbproject/profiler-build-impl.xml.stylesheet.CRC32=42cb6bcf
+1
Ver Arquivo
@@ -119,6 +119,7 @@ is divided into following sections:
<test name="${profile.class}"/>
<classpath>
<path path="${run.test.classpath}"/>
<path refid="test.runpath"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
+58 -56
Ver Arquivo
@@ -1,56 +1,58 @@
application.args=
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/jna.jar
dist.javadoc.dir=${dist.dir}/javadoc
file.reference.jnalib-src=src
jar.compress=false
javac.classpath=
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.source=1.5
javac.target=1.5
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=
meta.inf.dir=${src.dir}/META-INF
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-Djava.library.path=./native/testlib/Debug;./native/jnidispatch/Debug
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
src.dir=${file.reference.jnalib-src}
test.src.dir=test
application.args=
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/jna.jar
dist.javadoc.dir=${dist.dir}/javadoc
excludes=
file.reference.jnalib-src=src
includes=**
jar.compress=false
javac.classpath=
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.source=1.5
javac.target=1.5
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit.classpath}}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=
meta.inf.dir=${src.dir}/META-INF
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-Djava.library.path=./native/testlib/Debug;./native/jnidispatch/Debug
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
src.dir=${file.reference.jnalib-src}
test.src.dir=test
+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>
Arquivo executável
+241
Ver Arquivo
@@ -0,0 +1,241 @@
<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>
<li>Attempt to force unload of jnidispatch library prior to deleting it (w32).
<li>Added amd64 targets for OSX, FreeBSD, and Solaris.
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Reduce space allocated for invocation arguments.
<li>Fix NPE when NativeMapped type is used in a Structure.
<li>Fix some X11 type mappings for 64-bit.
<li>Fix OSX Leopard/JRE1.5+ window transparency.
<li>Fix window alpha compositing on X11.
<li>Fix loading of libraries with unicode names on OSX.
</ul>
<h2>Release 3.0.1</h2>
<b>Features</b><br>
<ul>
<li>Improve transparent window drawing performance on w32
<li>Use closure allocation from libffi
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Ensure nested structure arrays initialized with Structure.toArray use the
appropriate native memory.
<li>Ensure structure size is calculated prior to converting to array
<li>Avoid creating new windows when setting a window mask
<li>Fix bug in Pointer.setChar.
</ul>
<h2>Release 3.0</h2>
<b>Features</b><br>
<ul>
<li>More supported platforms, via GCC's libffi (wmeissner)
<li>Support struct by value as parameter and return value (duncan)
<li>Support struct by reference within structures
<li>Provide access to native peer for java.awt.Component
<li>Provide access to native peer on OS X.
<li>Support MINGW32 builds (fullung)
<li>Allow per-field Structure read/write by field name
<li>Avoid writing Structure fields marked 'volatile'
<li>Read and wrap function pointers in Structure fields when read with a Java
proxy to allow easy Java-side invocation (Ken Larson)
<li>Support array-backed Buffers as arguments (wmeissner)
<li>Auto-conversion of custom types (wmeissner)
<li>Allow pointer type-safety
<li>Optional VM crash protection, via Native.setProtected(boolean)
<li>Auto-convert WString[]
<li>Provide library synchronization wrapper similar to Collections.synchronizedX
<li>Support lookup of OSX framework libraries by name
<li>Explicit access to shared library global data
<li>Invocation interception to facilitate translation of C preprocessor macros
and inline functions
<li>Provide utility to determine Web Start native library cache location;
auto-include this path if jnidispatch is included as a <nativelib>
(robertengels)
<li>Provide access to aligned memory
<li>Versioning information embedded in jna.jar and native library
</ul>
<b>Bug Fixes</b><br>
<li>Avoid attempts to free native library if it failed to load (wmeissner)
<li>Explicitly check method signatures for varargs instead of heuristically
guessing (wmeissner)
<li>Disallow declaring Pointer-derived fields in Structures (Function, Memory)
<li>Ensure Object.toString/hashCode/equals methods are intercepted on proxyied
interfaces
<li>Update X11 library for 64-bit use (wmeissner)
<li>Properly map arrays of char*/wchar_t* under w32
<li>Allow Pointer[] as a Structure field and Function argument
<li>Fix some misleading Structure error messages
<li>Properly preserve/return GetLastError/errno after native calls
<li>Allocate executable memory on w32 to avoid errors with hardware-enforced
data execution protection (DEP)
<li>Fix VM crash on w32 stdcall callbacks
<li>Use long offsets and sizes rather than ints (64-bit safe)
<li>Properly clean up references and release closure memory on JNI_Unload
<li>Use simpler AWT/JAWT library loading workaround
<li>Avoid changing array references within a Structure on read
<h2>Release 2.5</h2>
<b>Features</b><br>
<ul>
<li>Unions
<li>Optimized shaped windows (chris deckers & olivier chafik); instantiation time
improved by about 2-3 orders of magnitude for large, mostly contiguous shapes
<li>Provide type mapping in callback arguments/results
<li>Provide access to ByteBuffer direct address as a Pointer
<li>Provide customization of native string encoding with jna.encoding system property
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Properly handle VMs with reversed Structure member storage
<li>Avoid making window undecorated when clearing window mask on X11
<li>Fix structure alignment bug on OSX/PPC when first element is > 4 bytes in size
<li>Clearing OSX window mask by setting to MASK_NONE now works properly
<li>Avoid index exceptions if native buffers are not NUL-terminated on string conversions
<li>Write initialized Structure[] argument memory prior to function calls
<li>Fix IllegalArgumentException reading WString into a Structure
<li>Clear memory when allocating a structure block (fixes VM crash)
<li>Remove versioned JAWT dependency on OSX, allowing use on 10.3/JRE1.4.
</ul>
<h2>Release 2.4</h2>
<b>Features</b><br>
<ul>
<li>Explicitly support unaligned structures
<li>Auto-reallocate structure arrays
<li>Automatic handling of w32 UNICODE/ASCII variants
<li>Automatic mapping of decorated w32 stdcall function names
<li>Customizable, automatic type conversion of arguments and results (wmeissner)
<li>Support char*[] arguments as Java String[]
<li>Structure supports Callback members (wmeissner)
<li>getByteBuffer from Pointer/Memory (wmeissner)
<li>Allow GC of native libraries
<li>Facilitate use from non-Java contexts (JRuby et al.) (wmeissner)
<li>Improve library path searching (wmeissner)
<li>Handle Structure[] arguments
<li>Handle native long arguments and return values
<li>Handle direct and array-based ByteBuffer arguments (wmeissner)
<li>Change default w32 build to use GCC (it's free, yo)
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Structure.toArray failed to initialize members
<li>Disallow explicit free of Structure/Memory
<li>Ensure native libraries are only loaded once until released
<li>Properly handle NULL when the return value is a Structure
<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>
-94
Ver Arquivo
@@ -1,94 +0,0 @@
Release 3.0
Features
* More supported platforms, via GCC's libffi (wmeissner)
* Support struct by value as parameter and return value (duncan)
* Support struct by reference within structures
* Provide access to native peer for java.awt.Component
* Provide access to native peer on OS X.
* Support MINGW32 builds (fullung)
* Allow per-field Structure read/write by field name
* Avoid writing Structure fields marked 'volatile'
* Read and wrap function pointers in Structure fields when read with a Java
proxy to allow easy Java-side invocation (Ken Larson)
* Support array-backed Buffers as arguments (wmeissner)
* Auto-conversion of custom types (wmeissner)
* Allow pointer type-safety
* Optional VM crash protection, via Native.setProtected(boolean)
* Auto-convert WString[]
* Provide library synchronization wrapper similar to Collections.synchronizedX
* Support lookup of OSX framework libraries by name
* Explicit access to shared library global data
* Invocation interception to facilitate translation of C preprocessor macros
and inline functions
* Provide utility to determine Web Start native library cache location;
auto-include this path if jnidispatch is included as a <nativelib>
(robertengels)
* Provide access to aligned memory
* Versioning information embedded in jna.jar and native library
Bug Fixes
* Avoid attempts to free native library if it failed to load (wmeissner)
* Explicitly check method signatures for varargs instead of heuristically
guessing (wmeissner)
* Disallow declaring Pointer-derived fields in Structures (Function, Memory)
* Ensure Object.toString/hashCode/equals methods are intercepted on proxyied
interfaces
* Update X11 library for 64-bit use (wmeissner)
* Properly map arrays of char*/wchar_t* under w32
* Allow Pointer[] as a Structure field and Function argument
* Fix some misleading Structure error messages
* Properly preserve/return GetLastError/errno after native calls
* Allocate executable memory on w32 to avoid errors with hardware-enforced
data execution protection (DEP)
* Fix VM crash on w32 stdcall callbacks
* Use long offsets and sizes rather than ints (64-bit safe)
* Properly clean up references and release closure memory on JNI_Unload
* Use simpler AWT/JAWT library loading workaround
* Avoid changing array references within a Structure on read
Release 2.5
Features
* Unions
* Optimized shaped windows (chris deckers & olivier chafik); instantiation time
improved by about 2-3 orders of magnitude for large, mostly contiguous shapes
* Provide type mapping in callback arguments/results
* Provide access to ByteBuffer direct address as a Pointer
* Provide customization of native string encoding with jna.encoding system property
Bug Fixes
* Properly handle VMs with reversed Structure member storage
* Avoid making window undecorated when clearing window mask on X11
* Fix structure alignment bug on OSX/PPC when first element is > 4 bytes in size
* Clearing OSX window mask by setting to MASK_NONE now works properly
* Avoid index exceptions if native buffers are not NUL-terminated on string conversions
* Write initialized Structure[] argument memory prior to function calls
* Fix IllegalArgumentException reading WString into a Structure
* Clear memory when allocating a structure block (fixes VM crash)
* Remove versioned JAWT dependency on OSX, allowing use on 10.3/JRE1.4.
Release 2.4
Features
* Explicitly support unaligned structures
* Auto-reallocate structure arrays
* Automatic handling of w32 UNICODE/ASCII variants
* Automatic mapping of decorated w32 stdcall function names
* Customizable, automatic type conversion of arguments and results (wmeissner)
* Support char*[] arguments as Java String[]
* Structure supports Callback members (wmeissner)
* getByteBuffer from Pointer/Memory (wmeissner)
* Allow GC of native libraries
* Facilitate use from non-Java contexts (JRuby et al.) (wmeissner)
* Improve library path searching (wmeissner)
* Handle Structure[] arguments
* Handle native long arguments and return values
* Handle direct and array-based ByteBuffer arguments (wmeissner)
* Change default w32 build to use GCC (it's free, yo)
Bug Fixes
* Structure.toArray failed to initialize members
* Disallow explicit free of Structure/Memory
* Ensure native libraries are only loaded once until released
* Properly handle NULL when the return value is a Structure
* Proper conversion to wchar_t on linux
* Copy full length of Java strings to C strings instead of stopping when a NUL
character is encountered
+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",
});
}
+75 -40
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);
}
@@ -141,31 +141,54 @@ class CallbackReference extends WeakReference {
return Pointer.class;
}
else if (NativeMapped.class.isAssignableFrom(cls)) {
return new NativeMappedConverter(cls).nativeType();
return NativeMappedConverter.getInstance(cls).nativeType();
}
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);
}
@@ -226,7 +249,7 @@ class CallbackReference extends WeakReference {
Class returnType = callbackMethod.getReturnType();
fromNative = new FromNativeConverter[argTypes.length];
if (NativeMapped.class.isAssignableFrom(returnType)) {
toNative = new NativeMappedConverter(returnType);
toNative = NativeMappedConverter.getInstance(returnType);
}
else if (mapper != null) {
toNative = mapper.getToNativeConverter(returnType);
@@ -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);
}
@@ -328,7 +355,7 @@ class CallbackReference extends WeakReference {
}
else if ((boolean.class == dstType || Boolean.class == dstType)
&& value instanceof Number) {
value = Boolean.valueOf(((Number)value).intValue() != 0);
value = Function.valueOf(((Number)value).intValue() != 0);
}
return 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;
@@ -406,7 +441,7 @@ class CallbackReference extends WeakReference {
else if (Library.Handler.OBJECT_EQUALS.equals(method)) {
Object o = args[0];
if (o != null && Proxy.isProxyClass(o.getClass())) {
return Boolean.valueOf(Proxy.getInvocationHandler(o) == this);
return Function.valueOf(Proxy.getInvocationHandler(o) == this);
}
return Boolean.FALSE;
}
+116 -41
Ver Arquivo
@@ -27,6 +27,16 @@ import java.util.Map;
* @see Pointer
*/
public class Function extends Pointer {
/** Any argument which implements this interface will have the
* {@link #read} method called immediately after function invocation.
*/
public interface PostCallRead {
/** Perform any necessary post-call synchronization. Normally this
* just means reading from native memory any changes made by
* the native function call.
*/
void read();
}
/** Maximum number of arguments supported by a JNA function call. */
public static final int MAX_NARGS = 256;
@@ -36,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.
@@ -196,7 +209,7 @@ public class Function extends Pointer {
Class nativeType = returnType;
FromNativeConverter resultConverter = null;
if (NativeMapped.class.isAssignableFrom(returnType)) {
NativeMappedConverter tc = new NativeMappedConverter(returnType);
NativeMappedConverter tc = NativeMappedConverter.getInstance(returnType);
resultConverter = tc;
nativeType = tc.nativeType();
}
@@ -224,33 +237,36 @@ public class Function extends Pointer {
// Sync all memory which might have been modified by the native call
if (inArgs != null) {
for (int i=0; i < inArgs.length; i++) {
Object arg = inArgs[i];
if (arg == null)
Object inArg = inArgs[i];
if (inArg == null)
continue;
if (arg instanceof Structure) {
if (!(arg instanceof Structure.ByValue)) {
((Structure)arg).read();
}
}
else if (args[i] instanceof StringArray) {
((StringArray)args[i]).read();
}
else if (args[i] instanceof PointerArray) {
PointerArray array = (PointerArray)args[i];
array.read();
if (Structure.ByReference[].class.isAssignableFrom(arg.getClass())) {
Class type = arg.getClass().getComponentType();
Structure[] ss = (Structure[])arg;
for (int si=0;si < ss.length;si++) {
Pointer p = array.getPointer(Pointer.SIZE * si);
ss[si] = Structure.updateStructureByReference(type, ss[si], p);
if (inArg instanceof Structure) {
if (!(inArg instanceof Structure.ByValue)) {
if (((Structure)inArg).getAutoRead()) {
((Structure)inArg).read();
}
}
}
else if (Structure[].class.isAssignableFrom(arg.getClass())) {
Structure[] ss = (Structure[])arg;
else if (args[i] instanceof PostCallRead) {
((PostCallRead)args[i]).read();
if (args[i] instanceof PointerArray) {
PointerArray array = (PointerArray)args[i];
if (Structure.ByReference[].class.isAssignableFrom(inArg.getClass())) {
Class type = inArg.getClass().getComponentType();
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
Pointer p = array.getPointer(Pointer.SIZE * si);
ss[si] = Structure.updateStructureByReference(type, ss[si], p);
}
}
}
}
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();
}
}
}
}
@@ -267,7 +283,7 @@ public class Function extends Pointer {
result = null;
}
else if (returnType==boolean.class || returnType==Boolean.class) {
result = Boolean.valueOf(invokeInt(callingConvention, args) != 0);
result = valueOf(invokeInt(callingConvention, args) != 0);
}
else if (returnType==byte.class || returnType==Byte.class) {
result = new Byte((byte)invokeInt(callingConvention, args));
@@ -295,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);
@@ -305,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 {
@@ -313,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;
}
}
@@ -324,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
@@ -338,7 +383,7 @@ public class Function extends Pointer {
Class type = arg.getClass();
ToNativeConverter converter = null;
if (NativeMapped.class.isAssignableFrom(type)) {
converter = new NativeMappedConverter(type);
converter = NativeMappedConverter.getInstance(type);
}
else if (mapper != null) {
converter = mapper.getToNativeConverter(type);
@@ -361,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) {
@@ -387,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);
@@ -405,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);
}
@@ -428,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;
}
@@ -556,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);
@@ -570,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)}.
*/
@@ -679,7 +749,7 @@ public class Function extends Pointer {
return false;
}
private static class PointerArray extends Memory {
private static class PointerArray extends Memory implements PostCallRead {
private Pointer[] original;
public PointerArray(Pointer[] arg) {
super(Pointer.SIZE * (arg.length+1));
@@ -695,4 +765,9 @@ public class Function extends Pointer {
}
}
}
/** Implementation of Boolean.valueOf for older VMs. */
static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
}
+3 -1
Ver Arquivo
@@ -73,7 +73,9 @@ public abstract class IntegerType extends Number implements NativeMapped {
}
public Object fromNative(Object nativeValue, FromNativeContext context) {
long value = ((Number) nativeValue).longValue();
// be forgiving of null values read from memory
long value = nativeValue == null
? 0 : ((Number) nativeValue).longValue();
try {
IntegerType number = (IntegerType) getClass().newInstance();
number.setValue(value);
+1 -1
Ver Arquivo
@@ -166,7 +166,7 @@ public interface Library {
else if (OBJECT_EQUALS.equals(method)) {
Object o = inArgs[0];
if (o != null && Proxy.isProxyClass(o.getClass())) {
return Boolean.valueOf(Proxy.getInvocationHandler(o) == this);
return Function.valueOf(Proxy.getInvocationHandler(o) == this);
}
return Boolean.FALSE;
}
+202 -66
Ver Arquivo
@@ -35,7 +35,9 @@ import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.WeakHashMap;
import com.sun.jna.Structure.ByReference;
@@ -81,14 +83,8 @@ public final class Native {
public static final int LONG_SIZE;
/** 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();
@@ -158,7 +154,7 @@ public final class Native {
throw new IllegalStateException("Component must be displayable");
// On X11 VMs prior to 1.5, the window must be visible
if (Platform.isX11()
&& System.getProperty("java.version").matches("^1\\.4\\..*")) {
&& System.getProperty("java.version").startsWith("1.4")) {
if (!c.isVisible()) {
throw new IllegalStateException("Component must be visible");
}
@@ -279,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;
}
}
}
@@ -301,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());
}
@@ -329,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) {
@@ -350,17 +371,20 @@ public final class Native {
}
/** Return the preferred {@link TypeMapper} for the given native interface.
* @see Library#OPTION_TYPE_MAPPER
* See {@link com.sun.jna.Library#OPTION_TYPE_MAPPER}.
*/
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) {
@@ -381,21 +405,23 @@ public final class Native {
}
/** Return the preferred structure alignment for the given native interface.
* @see Library#OPTION_STRUCTURE_ALIGNMENT
* See {@link com.sun.jna.Library#OPTION_STRUCTURE_ALIGNMENT}.
*/
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));
@@ -427,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;
@@ -437,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()) {
@@ -453,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);
@@ -470,12 +571,8 @@ public final class Native {
File lib = null;
if (url.getProtocol().toLowerCase().equals("file")) {
try {
lib = new File(URLDecoder.decode(url.getPath(), "UTF8"));
}
catch(UnsupportedEncodingException e) {
throw new Error("JRE is unexpectedly missing UTF8 encoding");
}
// NOTE: use older API for 1.3 compatibility
lib = new File(URLDecoder.decode(url.getPath()));
}
else {
InputStream is = Native.class.getResourceAsStream(resourceName);
@@ -489,9 +586,8 @@ public final class Native {
// Let Java pick the suffix
lib = File.createTempFile("jna", null);
lib.deleteOnExit();
// Have to remove the temp file after VM exit on w32
if (Platform.isWindows()) {
Runtime.getRuntime().addShutdownHook(new W32Cleanup(lib));
if (Platform.deleteNativeLibraryAfterVMExit()) {
Runtime.getRuntime().addShutdownHook(new DeleteNativeLibrary(lib));
}
fos = new FileOutputStream(lib);
int count;
@@ -501,7 +597,7 @@ public final class Native {
}
}
catch(IOException e) {
throw new Error("Failed to create temporary file for jnidispatch library", e);
throw new Error("Failed to create temporary file for jnidispatch library: " + e);
}
finally {
try { is.close(); } catch(IOException e) { }
@@ -592,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.
@@ -628,21 +725,48 @@ public final class Native {
* all native bits to be encapsulated in a private class).
* Instead, spawn a cleanup task to remove the file *after* the VM exits.
*/
public static class W32Cleanup extends Thread {
public static class DeleteNativeLibrary extends Thread {
private File file;
public W32Cleanup(File file) {
public DeleteNativeLibrary(File file) {
this.file = file;
}
public void run() {
private boolean unload(String path) {
// Reach into the bowels of ClassLoader to force the native
// library to unload
try {
Runtime.getRuntime().exec(new String[] {
System.getProperty("java.home") + "/bin/java",
"-cp", System.getProperty("java.class.path"),
getClass().getName(),
file.getAbsolutePath(),
});
ClassLoader cl = getClass().getClassLoader();
Field f = ClassLoader.class.getDeclaredField("nativeLibraries");
f.setAccessible(true);
List libs = (List)f.get(cl);
for (Iterator i = libs.iterator();i.hasNext();) {
Object lib = i.next();
f = lib.getClass().getDeclaredField("name");
f.setAccessible(true);
String name = (String)f.get(lib);
if (name.equals(path)) {
Method m = lib.getClass().getDeclaredMethod("finalize", new Class[0]);
m.setAccessible(true);
m.invoke(lib, new Object[0]);
return true;
}
}
}
catch(Exception e) {
}
return false;
}
public void run() {
if (!unload(file.getAbsolutePath()) || !file.delete()) {
try {
Runtime.getRuntime().exec(new String[] {
System.getProperty("java.home") + "/bin/java",
"-cp", System.getProperty("java.class.path"),
getClass().getName(),
file.getAbsolutePath(),
});
}
catch(IOException e) { e.printStackTrace(); }
}
catch(IOException e) { e.printStackTrace(); }
}
public static void main(String[] args) {
if (args.length == 1) {
@@ -652,8 +776,11 @@ public final class Native {
while (!file.delete() && file.exists()) {
try { Thread.sleep(10); }
catch(InterruptedException e) { }
if (System.currentTimeMillis() - start > 1000)
if (System.currentTimeMillis() - start > 5000) {
System.err.println("Could not remove temp file: "
+ file.getAbsolutePath());
break;
}
}
}
}
@@ -667,7 +794,7 @@ public final class Native {
*/
public static int getNativeSize(Class cls) {
if (NativeMapped.class.isAssignableFrom(cls)) {
cls = new NativeMappedConverter(cls).nativeType();
cls = NativeMappedConverter.getInstance(cls).nativeType();
}
// boolean defaults to 32 bit integer if not otherwise mapped
if (cls == boolean.class || cls == Boolean.class) return 4;
@@ -697,7 +824,7 @@ public final class Native {
/** Indicate whether the given class is supported as a native argument
* type.
*/
*/
public static boolean isSupportedNativeType(Class cls) {
if (Structure.class.isAssignableFrom(cls)) {
return true;
@@ -712,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);
+186 -94
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
@@ -24,10 +24,10 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
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.regex.Pattern;
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,49 +287,61 @@ 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);
}
/** Close the library when it is no longer referenced. */
protected void finalize() {
if (handle != 0) {
close(handle);
handle = 0;
dispose();
}
public void dispose() {
synchronized(libraries) {
libraries.remove(getName());
libraries.remove(getFile().getAbsolutePath());
libraries.remove(getFile().getName());
}
synchronized(this) {
if (handle != 0) {
close(handle);
handle = 0;
}
}
}
private static List initPaths(String key) {
String value = System.getProperty(key, "");
if ("".equals(value)) {
return Collections.EMPTY_LIST;
}
String[] paths = value.split(File.pathSeparator);
StringTokenizer st = new StringTokenizer(value, File.pathSeparator);
List list = new ArrayList();
for (int i=0;i < paths.length;i++) {
if (!"".equals(paths[i])) {
list.add(paths[i]);
while (st.hasMoreTokens()) {
String path = st.nextToken();
if (!"".equals(path)) {
list.add(path);
}
}
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);
@@ -306,7 +349,7 @@ public class NativeLibrary {
return file.getAbsolutePath();
}
}
//
// Default to returning the mapped library name and letting the system
// search for it
@@ -314,45 +357,67 @@ public class NativeLibrary {
return name;
}
private static String mapLibraryName(String libName) {
if (Platform.isMac()) {
if (libName.matches("lib.*\\.(dylib|jnilib)$")) {
if (libName.startsWith("lib")
&& (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()) {
//
// A specific version was requested - use as is for search
//
if (libName.matches("lib.*\\.so\\.[0-9]+$")) {
}
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.");
if (so != -1 && so + 4 < name.length()) {
for (int i=so+4;i < name.length();i++) {
char ch = name.charAt(i);
if (!Character.isDigit(ch) && ch != '.') {
return false;
}
}
return true;
}
}
return false;
}
/**
* matchLibrary is very Linux specific. It is here to deal with the case
* where there is no /usr/lib/libc.so, or it is not a valid symlink to
* /lib/libc.so.6.
* 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).
*/
private static String matchLibrary(final String libName, List searchPath) {
static String matchLibrary(final String libName, List searchPath) {
File lib = new File(libName);
if (lib.isAbsolute()) {
searchPath = Arrays.asList(new String[] { lib.getParent() });
}
FilenameFilter filter = new FilenameFilter() {
Pattern p = Pattern.compile("lib" + libName + "\\.so\\.[0-9]+$");
public boolean accept(File dir, String name) {
return p.matcher(name).matches();
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);
@@ -360,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);
@@ -395,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.
//
@@ -409,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);
@@ -1,22 +1,38 @@
/* 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.util.Map;
import java.util.WeakHashMap;
/** Provides type conversion for instances of {@link NativeMapped}. */
public class NativeMappedConverter implements TypeConverter {
private Class type;
private Class nativeType;
private NativeMapped instance;
private static Map converters = new WeakHashMap();
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);
if (nmc == null) {
nmc = new NativeMappedConverter(cls);
converters.put(cls, nmc);
}
return nmc;
}
}
public NativeMappedConverter(Class type) {
if (!NativeMapped.class.isAssignableFrom(type))
throw new IllegalArgumentException("Type must derive from "
@@ -25,7 +41,7 @@ public class NativeMappedConverter implements TypeConverter {
this.instance = defaultValue();
this.nativeType = instance.nativeType();
}
public NativeMapped defaultValue() {
try {
return (NativeMapped)type.newInstance();
@@ -50,6 +66,6 @@ public class NativeMappedConverter implements TypeConverter {
}
public Object toNative(Object value, ToNativeContext context) {
return ((NativeMapped)value).toNative();
return value == null ? defaultValue().toNative() : ((NativeMapped)value).toNative();
}
}
+3 -1
Ver Arquivo
@@ -10,6 +10,8 @@
*/
package com.sun.jna;
import java.nio.CharBuffer;
/** Provides a temporary allocation of an immutable C string
* (<code>const char*</code> or <code>const wchar_t*</code>) for use when
@@ -91,7 +93,7 @@ class NativeString implements CharSequence, Comparable {
}
public CharSequence subSequence(int start, int end) {
return value.subSequence(start, end);
return CharBuffer.wrap(value).subSequence(start, end);
}
public int compareTo(Object other) {
+24 -2
Ver Arquivo
@@ -17,6 +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 OPENBSD = 5;
private static final int WINDOWSCE = 6;
private static final int osType;
static {
@@ -27,6 +29,9 @@ public final class Platform {
else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
osType = MAC;
}
else if (osName.startsWith("Windows CE")) {
osType = WINDOWSCE;
}
else if (osName.startsWith("Windows")) {
osType = WINDOWS;
}
@@ -36,6 +41,9 @@ public final class Platform {
else if (osName.startsWith("FreeBSD")) {
osType = FREEBSD;
}
else if (osName.startsWith("OpenBSD")) {
osType = OPENBSD;
}
else {
osType = UNSPECIFIED;
}
@@ -47,8 +55,11 @@ public final class Platform {
public static final boolean isLinux() {
return osType == LINUX;
}
public static final boolean isWindowsCE() {
return osType == WINDOWSCE;
}
public static final boolean isWindows() {
return osType == WINDOWS;
return osType == WINDOWS || osType == WINDOWSCE;
}
public static final boolean isSolaris() {
return osType == SOLARIS;
@@ -56,8 +67,19 @@ 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 FS or do some other X11-specific test
// TODO: check filesystem for /usr/X11 or some other X11-specific test
return !Platform.isWindows() && !Platform.isMac();
}
public static final boolean deleteNativeLibraryAfterVMExit() {
return osType == WINDOWS;
}
public static final boolean hasRuntimeExec() {
if (isWindowsCE() && "J9".equals(System.getProperty("java.vm.name")))
return false;
return true;
}
}
+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
//////////////////////////////////////////////////////////////////////////
+20 -3
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;
@@ -8,7 +20,7 @@ import java.util.List;
* pointers. An extra NULL pointer is always added to the end of the native
* pointer array for convenience.
*/
public class StringArray extends Memory {
public class StringArray extends Memory implements Function.PostCallRead {
private boolean wide;
private List natives = new ArrayList();
private Object[] original;
@@ -43,8 +55,13 @@ public class StringArray extends Memory {
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) {
+3 -1
Ver Arquivo
@@ -12,6 +12,8 @@
*/
package com.sun.jna;
import java.nio.CharBuffer;
/** Simple wrapper class to identify a wide string argument or return type.
* @author twall@users.sf.net
*/
@@ -39,6 +41,6 @@ public final class WString implements CharSequence, Comparable {
return toString().charAt(index);
}
public CharSequence subSequence(int start, int end) {
return toString().subSequence(start, end);
return CharBuffer.wrap(toString()).subSequence(start, end);
}
}
+40 -15
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.examples;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
@@ -57,8 +58,6 @@ import com.sun.jna.Pointer;
import com.sun.jna.examples.unix.X11;
import com.sun.jna.examples.unix.X11.Display;
import com.sun.jna.examples.unix.X11.GC;
import com.sun.jna.examples.unix.X11.Pixmap;
import com.sun.jna.examples.unix.X11.Visual;
import com.sun.jna.examples.unix.X11.XSetWindowAttributes;
import com.sun.jna.examples.win32.GDI32;
import com.sun.jna.examples.win32.User32;
@@ -89,6 +88,10 @@ public class AlphaMaskDemo implements Runnable {
private float alpha = 1f;
private Image image;
private void update() {
update(false, true);
}
private void update(boolean a, boolean i) {
String os = System.getProperty("os.name");
if (os.startsWith("Windows"))
@@ -119,6 +122,8 @@ public class AlphaMaskDemo implements Runnable {
}
}
private com.sun.jna.Memory buffer;
private int[] pixels;
private void updateX11(boolean a, boolean i) {
X11 x11 = X11.INSTANCE;
X11.Window win = X11.Window.None;
@@ -129,11 +134,6 @@ public class AlphaMaskDemo implements Runnable {
if (System.getProperty("java.version").matches("^1\\.4\\..*"))
alphaWindow.setVisible(true);
win = new X11.Window((int)Native.getWindowID(alphaWindow));
XSetWindowAttributes xswa = new XSetWindowAttributes();
xswa.background_pixel = new NativeLong(0x0);
Visual visual = x11.XDefaultVisual(dpy, x11.XDefaultScreen(dpy));
xswa.colormap = x11.XCreateColormap(dpy, win, visual, X11.AllocNone);
x11.XChangeWindowAttributes(dpy, win, new NativeLong(X11.CWBackPixel|X11.CWColormap), xswa);
Window parent = alphaWindow.getOwner();
Point where = parent.getLocationOnScreen();
where.translate(parent.getWidth(), 0);
@@ -149,34 +149,54 @@ public class AlphaMaskDemo implements Runnable {
int w = image.getWidth(null);
int h = image.getHeight(null);
alphaWindow.setSize(w, h);
if (buffer == null || buffer.getSize() != w*h*4) {
buffer = new com.sun.jna.Memory(w*h*4);
pixels = new int[w*h];
}
BufferedImage buf = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = buf.getGraphics();
g.drawImage(image, 0, 0, w, h, null);
long start = System.currentTimeMillis();
long blitTime, putImageTime, write;
GC gc = x11.XCreateGC(dpy, win, new NativeLong(0), null);
Pixmap pixmap = x11.XCreatePixmap(dpy, win, w, h, 32);
long gcTime = System.currentTimeMillis();
try {
x11.XSetForeground(dpy, gc, new NativeLong(0));
x11.XFillRectangle(dpy, pixmap, gc, 0, 0, w, h);
Raster raster = buf.getData();
int[] pixel = new int[4];
for (int y=0;y < h;y++) {
for (int x=0;x < w;x++) {
raster.getPixel(x, h-y-1, pixel);
raster.getPixel(x, y, pixel);
int alpha = (pixel[3]&0xFF)<<24;
int red = (pixel[2]&0xFF);
int green = (pixel[1]&0xFF)<<8;
int blue = (pixel[0]&0xFF)<<16;
x11.XSetForeground(dpy, gc, new NativeLong(alpha|red|green|blue));
x11.XFillRectangle(dpy, pixmap, gc, x, h-y-1, 1, 1);
pixels[y*w+x] = alpha|red|green|blue;
}
}
x11.XCopyArea(dpy, pixmap, win, gc, 0, 0, w, h, 0, 0);
blitTime = System.currentTimeMillis();
X11.XWindowAttributes xwa = new X11.XWindowAttributes();
x11.XGetWindowAttributes(dpy, win, xwa);
X11.XImage image = x11.XCreateImage(dpy, xwa.visual,
32, X11.ZPixmap,
0, buffer, w, h, 32, w*4);
buffer.write(0, pixels, 0, pixels.length);
write = System.currentTimeMillis();
x11.XPutImage(dpy, win, gc, image, 0,0,0,0,w,h);
x11.XFree(image.getPointer());
putImageTime = System.currentTimeMillis();
}
finally {
if (gc != null)
x11.XFreeGC(dpy, gc);
}
long end = System.currentTimeMillis();
//System.out.println("gc: " + (gcTime-start) + "ms");
//System.out.println("blit: " + (blitTime-gcTime) + "ms");
//System.out.println("write: " + (write-blitTime) + "ms");
//System.out.println("put image: " + (putImageTime-write) + "ms");
//System.out.println("total: " + (end-start) + "ms");
}
}
finally {
@@ -469,6 +489,11 @@ public class AlphaMaskDemo implements Runnable {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
centerOnScreen(frame);
frame.setVisible(true);
p.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
update();
}
});
try {
URL url = getClass().getResource("tardis.png");
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 Timothy Wall, All Rights Reserved This library is
* 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
@@ -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;
@@ -33,6 +34,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
@@ -50,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;
@@ -106,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");
@@ -251,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;
}
}
@@ -36,6 +36,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Calendar;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
@@ -198,8 +199,6 @@ public class ShapedWindowDemo {
private Point offset;
private void showPopup(MouseEvent e) {
final JPopupMenu m = new JPopupMenu();
// use a heavyweight popup to avoid having it clipped
// by the window mask
m.add(new AbstractAction("Hide") {
public void actionPerformed(ActionEvent e) {
frame.setState(JFrame.ICONIFIED);
@@ -240,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);
@@ -250,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();
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
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>
@@ -38,7 +38,7 @@ public class StdCallFunctionMapper implements FunctionMapper {
/** Override this to handle any custom class mappings. */
protected int getArgumentNativeStackSize(Class cls) {
if (NativeMapped.class.isAssignableFrom(cls)) {
cls = new NativeMappedConverter(cls).nativeType();
cls = NativeMappedConverter.getInstance(cls).nativeType();
}
if (cls.isArray()) {
return Pointer.SIZE;
@@ -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;
}
@@ -48,10 +48,10 @@ public class W32APITypeMapper extends DefaultTypeMapper {
public Object fromNative(Object value, FromNativeContext context) {
if (value == null)
return null;
return ((Pointer)value).getString(0, true);
return value.toString();
}
public Class nativeType() {
return Pointer.class;
return WString.class;
}
};
addTypeConverter(String.class, stringConverter);
@@ -62,7 +62,7 @@ public class W32APITypeMapper extends DefaultTypeMapper {
return new Integer(Boolean.TRUE.equals(value) ? 1 : 0);
}
public Object fromNative(Object value, FromNativeContext context) {
return Boolean.valueOf(((Integer)value).intValue() != 0);
return ((Integer)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
}
public Class nativeType() {
// BOOL is 32-bit int
+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);
}
}
+29 -7
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,20 +84,25 @@ 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;
int dot = libName.lastIndexOf(".");
if (dot != -1) {
newLibName += libName.substring(dot, libName.length());
if (Platform.isMac()) {
newLibName += ".dylib";
}
else {
newLibName += libName.substring(dot, libName.length());
}
}
File dst = new File(tmp, newLibName);
//dst.deleteOnExit();
dst.deleteOnExit();
copy(src, dst);
NativeLibrary.addSearchPath(UNICODE, tmp);
NativeLibrary.getInstance(UNICODE);
@@ -117,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) {
+52 -1
Ver Arquivo
@@ -14,6 +14,9 @@ package com.sun.jna;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
public class NativeLibraryTest extends TestCase {
@@ -108,7 +111,7 @@ public class NativeLibraryTest extends TestCase {
assertNull("Library not GC'd", ref.get());
}
public void testLoadPathVariations() {
public void testLoadFrameworkLibrary() {
if (Platform.isMac()) {
try {
NativeLibrary lib = NativeLibrary.getInstance("CoreServices");
@@ -130,7 +133,55 @@ public class NativeLibraryTest extends TestCase {
global.setInt(0, MAGIC+1);
assertEquals("Library global variable not updated", MAGIC+1, global.getInt(0));
}
public void testMatchUnversionedToVersioned() throws Exception {
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 = new File(dir, "lib" + name + ".so.1.0");
lib1.createNewFile();
lib1.deleteOnExit();
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("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) {
junit.textui.TestRunner.run(NativeLibraryTest.class);
}
+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));
}
}
+336 -129
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,8 +18,8 @@ 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;
import com.sun.jna.ptr.LongByReference;
@@ -27,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);
}
@@ -39,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;
@@ -54,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;
@@ -78,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;
@@ -93,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++) {
@@ -161,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 {
@@ -175,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) {
@@ -202,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 { }
@@ -215,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];
@@ -231,14 +231,18 @@ public class StructureTest extends TestCase {
s.write();
s.read();
}
public void testStructureArrayField() {
class TestStructure extends Structure {
public PublicTestStructure[] inner = new PublicTestStructure[2];
public PublicTestStructure[] inner2 = (PublicTestStructure[])
new PublicTestStructure().toArray(2);
}
TestStructure s = new TestStructure();
int innerSize = new PublicTestStructure().size();
assertEquals("Wrong size for structure with nested array of struct",
s.inner.length * new PublicTestStructure().size(), s.size());
s.inner.length * innerSize + s.inner2.length * innerSize,
s.size());
s.write();
assertNotNull("Inner array elements should auto-initialize", s.inner[0]);
s.inner[0].x = s.inner[0].y = -1;
@@ -248,8 +252,29 @@ 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.inner2[0].getPointer());
}
public static class ToArrayTestStructure extends Structure {
public PublicTestStructure[] inner =
(PublicTestStructure[])new PublicTestStructure().toArray(2);
}
public void testToArrayWithStructureArrayField() {
ToArrayTestStructure[] array =
(ToArrayTestStructure[])new ToArrayTestStructure().toArray(2);
assertEquals("Wrong address for top-level array element",
array[0].getPointer().share(array[0].size()),
array[1].getPointer());
assertEquals("Wrong address for nested array element",
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;
@@ -269,65 +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', 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;
@@ -335,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;
@@ -347,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);
@@ -355,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;
@@ -368,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);
@@ -377,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) {
@@ -398,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;
}
@@ -409,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() {
@@ -426,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;
@@ -467,7 +489,7 @@ public class StructureTest extends TestCase {
catch(IllegalStateException e) {
}
}
public static class ArrayOfStructure extends Structure {
public Structure[] array;
}
@@ -482,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;
@@ -497,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 {
@@ -507,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;
@@ -537,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();
@@ -552,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();
@@ -577,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]);
@@ -618,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;
@@ -637,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];
@@ -650,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;
@@ -665,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
@@ -677,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;
@@ -701,4 +747,165 @@ 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;
}
TestStructure s = new TestStructure();
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);
}

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