Comparar commits
241 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 830ec91cbf | |||
| aee2d55fab | |||
| 89ed7982e7 | |||
| 9f702c89ab | |||
| 2f76efd0f6 | |||
| fae18c72c3 | |||
| 1586f6ee2b | |||
| 4ce6214526 | |||
| e370e4b65e | |||
| 944de2d3f5 | |||
| f32146368d | |||
| 8d45e9b016 | |||
| 70227861ff | |||
| 20e542516b | |||
| 73ad21df73 | |||
| a67fe7e43d | |||
| a15ddd9f88 | |||
| b27f9bf930 | |||
| d5c28f98f1 | |||
| 16b283ed00 | |||
| 97b43889a1 | |||
| 05efa12411 | |||
| 3e60495232 | |||
| 45522b0710 | |||
| d67d25eb7b | |||
| 2538690fb4 | |||
| 4c23b2518e | |||
| 9daade9816 | |||
| 5f925f0070 | |||
| 38b0cd7780 | |||
| e46391042b | |||
| 553a03b05f | |||
| 24c1cc4efe | |||
| f6eabe7b58 | |||
| de2de1fdc7 | |||
| 8184ac8843 | |||
| a57d82d4cd | |||
| a266ef7337 | |||
| b30ca23180 | |||
| db5c8f00fc | |||
| d1bbacb06e | |||
| bff4e3b0fd | |||
| 14248ddbd9 | |||
| 391f39d291 | |||
| b4354efa8b | |||
| 686588a6e5 | |||
| 294267a605 | |||
| 7b53b9108b | |||
| 15be9ab501 | |||
| 7cfcd2daef | |||
| 6070429eec | |||
| b5f41ef6c7 | |||
| 716588a8fb | |||
| 95bc92f005 | |||
| 23425abe9d | |||
| 3bab5e1e78 | |||
| 79ed7e81b1 | |||
| a59e58cc94 | |||
| 72bd12e394 | |||
| 2c667ca016 | |||
| 209c4d724f | |||
| 95cf641f50 | |||
| 85750fd065 | |||
| 402b5c7f81 | |||
| be6f52b796 | |||
| f4e6c6ad94 | |||
| 99fe59cee9 | |||
| 0e80ba8b91 | |||
| 8965efdce1 | |||
| 1393a94804 | |||
| 52e558d877 | |||
| d9948105f1 | |||
| 87c91c1c04 | |||
| f15e471371 | |||
| fc0a83933d | |||
| f1cf2fe218 | |||
| 7a5679cb65 | |||
| 571b4604db | |||
| 29e15a40db | |||
| 6fb2286fa4 | |||
| ab2f78c7b4 | |||
| f9b918a05b | |||
| a46cde174a | |||
| 6eee0f8741 | |||
| 28d31bb9f6 | |||
| 23128be17f | |||
| 130885fda7 | |||
| c4fc42f8f4 | |||
| 21e73c5fb9 | |||
| b635bf5591 | |||
| be594bb1f6 | |||
| 543e3fca98 | |||
| b385d76dc6 | |||
| 2adc88fec3 | |||
| 2a9e2ceb61 | |||
| 47fa804469 | |||
| f70c01eee7 | |||
| eb4ea07a2d | |||
| 55cd72baaa | |||
| 940076d101 | |||
| 93ebb9f7a9 | |||
| 1a17ea52d8 | |||
| 68bc0c0c7c | |||
| 0e7dd6b350 | |||
| b3b0bf3845 | |||
| ddc32f1e43 | |||
| c9de508a2c | |||
| fac68bca4e | |||
| eaf250c3c6 | |||
| 8b99772d29 | |||
| 862a32e97e | |||
| 6cfb84d6ee | |||
| 2fda7ca6f6 | |||
| f2aecb53bc | |||
| 05fdc2f17a | |||
| b9868b993c | |||
| 573d8eefd1 | |||
| 51d64f29e6 | |||
| a39ab60ae5 | |||
| ba9671fae5 | |||
| a9340f354d | |||
| f9d6b069f7 | |||
| c363d5790d | |||
| 15a50d2a26 | |||
| bffc188151 | |||
| e78205430c | |||
| 4ef76d4f85 | |||
| 967da46793 | |||
| 46899503bd | |||
| 2dcf0f774c | |||
| d669db0cab | |||
| f8aabcc50a | |||
| 4bb3ece8dc | |||
| 495a7765d2 | |||
| 225296f253 | |||
| 52e6900e7a | |||
| 557bff1465 | |||
| add32ac107 | |||
| f7699b98fb | |||
| 05a8ec1fec | |||
| 004e63c433 | |||
| 898f41b95a | |||
| 859a6a75aa | |||
| b90dae6448 | |||
| dc1ddf4cff | |||
| 46ef5d86c3 | |||
| ac63a6b125 | |||
| 72778c97df | |||
| b4b86081f9 | |||
| e4a47a4ca5 | |||
| 79c60f6d4e | |||
| 4c4d55e0dc | |||
| 9504416beb | |||
| 99586d9b3f | |||
| 65b19cbbd3 | |||
| 7b64f4443d | |||
| abb2e857be | |||
| df10745963 | |||
| 3d729595d1 | |||
| 96a38d1895 | |||
| b4c1390af8 | |||
| e9604ac212 | |||
| ea3a4b34ea | |||
| 79a0d92161 | |||
| b10c40260c | |||
| 9e056d2097 | |||
| 8a250c5994 | |||
| e311ac3269 | |||
| 28078a2d0c | |||
| 7def8c1bbf | |||
| 24ca11387e | |||
| bccc9583c1 | |||
| 9643747b17 | |||
| c695848092 | |||
| 5011613e4c | |||
| 6cc7f69a59 | |||
| db6678637b | |||
| 93892e12a2 | |||
| c196aab89d | |||
| 54a7718b88 | |||
| cec6e6175a | |||
| bc5036bd34 | |||
| 021826eb1b | |||
| facd071967 | |||
| 486e81ad77 | |||
| 872cd3d7c0 | |||
| ca9851b311 | |||
| 2fa0940d45 | |||
| 3485338386 | |||
| 786a821f3f | |||
| da1c9c5ea5 | |||
| 93d8cce7ac | |||
| 5086ba2a3b | |||
| 4cf8611dcd | |||
| 101e9d705a | |||
| 7d8bfa1b62 | |||
| 5dcf9e2f41 | |||
| cdf18b6c4d | |||
| 609ce3b6e0 | |||
| 3ba8be2e21 | |||
| 6b13a97ce4 | |||
| 130e40957e | |||
| a7b28317d7 | |||
| 29fcd0fdcf | |||
| 9d5f63e543 | |||
| 208c28ead2 | |||
| 447d5ee94b | |||
| bb443add17 | |||
| cb954773ed | |||
| 89749c7eb1 | |||
| 30146f8744 | |||
| a623f374b1 | |||
| b41584feb3 | |||
| 77d5bbb767 | |||
| 171d428d3a | |||
| 61254c6cc4 | |||
| 44b3a8952e | |||
| 0fc8c5e7e9 | |||
| 6d969eb92f | |||
| 26ea0f81ca | |||
| dc45e38f11 | |||
| 9d5db40d3f | |||
| 9e25d52679 | |||
| 1f98d4f6ff | |||
| b73883ce1d | |||
| 7af42da5d2 | |||
| cf75057b67 | |||
| e5b1841030 | |||
| 57325a22a5 | |||
| c640166cf8 | |||
| 4b4c362c03 | |||
| c71bfb1602 | |||
| 022e6349c1 | |||
| 917671ac9a | |||
| a108975d78 | |||
| 62d31c5902 | |||
| 5d28314ee3 | |||
| 1b22109f95 | |||
| e5c05bfd66 | |||
| 62e97858d7 | |||
| b9da9b977e |
+22
-10
@@ -18,24 +18,34 @@
|
||||
* get system process information, basic process control
|
||||
* additional file utilities (meta info, free space, etc)
|
||||
* enforce window minimum/maximum size (workaround java bug)
|
||||
* OSX ObjC access
|
||||
* OSX ObjC access (see rococoa)
|
||||
|
||||
# TODO
|
||||
|
||||
* make native dll extraction from jar public
|
||||
|
||||
* Callback.PostCallWrite.write() cf PostCallRead; do Structure.write for any
|
||||
arguments as well
|
||||
|
||||
* pointer.setValue(), to handle NativeMapped types and move read/writeValue
|
||||
methods out of Structure, to be used by Function w/NativeMapped[] parameter
|
||||
|
||||
* GetPrimitiveArrayCritical: use this if flagged (by annotation? method name?)
|
||||
|
||||
* MethodArgument/ReturnMapper: per method mapping of arguments/return type.
|
||||
Can use annotations as shorthand to initialize a map, but basically set up a
|
||||
per-NativeLibrary (or per-Function?) map of methods to mappers.
|
||||
|
||||
Requires separate compilation of annotation handling.
|
||||
|
||||
* 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
|
||||
o see JNAerator
|
||||
|
||||
* stdcall/w32 underscore prefix issue
|
||||
|
||||
* should structure offsets be "long"?
|
||||
|
||||
* allow return of W/String[] or Pointer[], if array is NULL-terminated?
|
||||
|
||||
* Direct buffers should be used where
|
||||
hotspot inlining can improve performance.
|
||||
|
||||
* should structure offsets be 64-bit? technically yes, but in practice I don't
|
||||
think a structure that big actually works.
|
||||
|
||||
* (maybe) move all native functions into Native (limit header files, easier
|
||||
management)
|
||||
@@ -48,6 +58,8 @@
|
||||
(less robust but easier to change).
|
||||
o bounds checking is handled by IntegerType (pass in a long, get an
|
||||
exception if the value is out of bounds).
|
||||
o when used as struct fields, could allow detection of field order by order
|
||||
of initialization (requires all-or-nothing usage, though)
|
||||
|
||||
* packaging: 'types', 'convert/marshal' subpackages?
|
||||
note: marshal/unmarshal vs to/fromnative: to/fromnative is more
|
||||
|
||||
+131
-58
@@ -17,6 +17,8 @@
|
||||
<property name="jar" value="${name}.jar"/>
|
||||
<property name="debug" value="true"/>
|
||||
<property name="debug.native" value="false"/>
|
||||
<property name="cflags_extra.native" value=""/>
|
||||
<property name="dynlink.native" value="false"/>
|
||||
<property name="native" location="native"/>
|
||||
<property name="src" location="src"/>
|
||||
<property name="dist" location="dist"/>
|
||||
@@ -26,25 +28,25 @@
|
||||
<property name="stylesheet" location="${javadoc}/doc/css/javadoc.css"/>
|
||||
<property name="vendor" value="JNA Development Team"/>
|
||||
<property name="copyright"
|
||||
value="Copyright &copy; 2007 Timothy Wall. All Rights Reserved."/>
|
||||
value="Copyright &copy; 2007-2008 Timothy Wall. All Rights Reserved."/>
|
||||
<buildnumber/>
|
||||
<!-- JNA library release version -->
|
||||
<property name="jna.major" value="3"/>
|
||||
<property name="jna.minor" value="0"/>
|
||||
<property name="jna.revision" value="2"/>
|
||||
<property name="jna.minor" value="1"/>
|
||||
<property name="jna.revision" value="0"/>
|
||||
<property name="jna.build" value="${build.number}"/>
|
||||
<property name="jna.version" value="${jna.major}.${jna.minor}.${jna.revision}"/>
|
||||
<!-- jnidispatch library release version -->
|
||||
<property name="jni.major" value="3"/>
|
||||
<property name="jni.minor" value="0"/>
|
||||
<property name="jni.revision" value="3"/>
|
||||
<property name="jni.minor" value="1"/>
|
||||
<property name="jni.revision" value="0"/>
|
||||
<property name="jni.build" value="${build.number}"/>
|
||||
<property name="jni.version" value="${jni.major}.${jni.minor}.${jni.revision}"/>
|
||||
<property name="jni.md5" value="892beacd437514d23ed9b1cefeb2ead6"/>
|
||||
<property name="jni.md5" value="816e53324203bcffe46f43e482e5c286"/>
|
||||
<property name="spec.title" value="Java Native Access (JNA)"/>
|
||||
<property name="spec.vendor" value="${vendor}"/>
|
||||
<property name="spec.version" value="${jna.major}"/>
|
||||
<property name="impl.title" value="${spec.title}"/>
|
||||
<property name="impl.title" value="com.sun.jna"/>
|
||||
<property name="impl.vendor" value="${spec.vendor}"/>
|
||||
<property name="impl.version" value="${jna.version} b${jna.build}"/>
|
||||
|
||||
@@ -64,19 +66,49 @@
|
||||
<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="(<version>).*(</version>)"
|
||||
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>
|
||||
<condition property="ld.preload" value="LD_PRELOAD_64" else="LD_PRELOAD">
|
||||
<and>
|
||||
<os name="SunOS"/>
|
||||
<equals arg1="${vm.arch}" arg2="-d64"/>
|
||||
</and>
|
||||
</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"/>
|
||||
<property name="reports" value="${build}/reports"/>
|
||||
|
||||
<!-- Add other supported platforms here -->
|
||||
<condition property="jre.arch" value="i386">
|
||||
<equals arg1="x86" arg2="${os.arch}"/>
|
||||
</condition>
|
||||
<condition property="jre.arch" value="amd64">
|
||||
<equals arg1="x86_64" arg2="${os.arch}"/>
|
||||
</condition>
|
||||
<property name="jre.arch" value="${os.arch}"/>
|
||||
<condition property="os.prefix" value="linux-${jre.arch}">
|
||||
<os name="Linux"/>
|
||||
</condition>
|
||||
<condition property="os.prefix" value="win32-${os.arch}">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
<condition property="os.prefix" value="linux-${os.arch}">
|
||||
<os name="Linux"/>
|
||||
</condition>
|
||||
<!-- Darwin builds are universal, no arch required -->
|
||||
<condition property="os.prefix" value="darwin">
|
||||
<os family="mac"/>
|
||||
@@ -87,6 +119,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"/>
|
||||
@@ -95,7 +130,10 @@
|
||||
<available file="${java.home}/../include"/>
|
||||
</condition>
|
||||
<fail unless="jdk.home" message="JAVA_HOME/java.home must be a JDK, not JRE"/>
|
||||
|
||||
<condition property="libjsig"
|
||||
value="${java.home}/lib/${jre.arch}/libjsig.so" else="">
|
||||
<available file="${java.home}/lib/${jre.arch}/libjsig.so"/>
|
||||
</condition>
|
||||
<property name="native.jar" value="${os.prefix}.jar"/>
|
||||
<property name="build.native" location="${build}/native"/>
|
||||
<property name="md5.file" location="${build.native}/sig"/>
|
||||
@@ -129,7 +167,7 @@
|
||||
<pathelement path="${build}/${jar}"/>
|
||||
<pathelement path="${build}/examples.jar"/>
|
||||
<pathelement path="${test.classes}"/>
|
||||
<pathelement path="${ant.home}/lib/clover.jar"/>
|
||||
<pathelement path="lib/clover.jar"/>
|
||||
<path refid="test.libs"/>
|
||||
</path>
|
||||
</target>
|
||||
@@ -161,15 +199,19 @@
|
||||
description="Build primary jar">
|
||||
<jar jarfile="${build}/${jar}">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Title" value="${impl.title}"/>
|
||||
<attribute name="Implementation-Vendor" value="${vendor}"/>
|
||||
<attribute name="Implementation-Version" value="${impl.version}"/>
|
||||
<attribute name="Specification-Title" value="${spec.title}"/>
|
||||
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
|
||||
<attribute name="Specification-Version" value="${spec.version}"/>
|
||||
<attribute name="Main-Class" value="com.sun.jna.Native"/>
|
||||
<section name="com/sun/jna/">
|
||||
<attribute name="Implementation-Title" value="${impl.title}"/>
|
||||
<attribute name="Implementation-Vendor" value="${vendor}"/>
|
||||
<attribute name="Implementation-Version" value="${impl.version}"/>
|
||||
<attribute name="Specification-Title" value="${spec.title}"/>
|
||||
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
|
||||
<attribute name="Specification-Version" value="${spec.version}"/>
|
||||
</section>
|
||||
</manifest>
|
||||
<fileset dir="${classes}"><patternset refid="jar-compiled"/></fileset>
|
||||
<fileset dir="${classes}" excludes="${jar.omitted}">
|
||||
<patternset refid="jar-compiled"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
</target>
|
||||
<target name="examples" depends="jar,native">
|
||||
@@ -196,6 +238,9 @@
|
||||
<condition property="grep" value="/usr/sfw/bin/ggrep">
|
||||
<os name="SunOS"/>
|
||||
</condition>
|
||||
<condition property="grep" value="ggrep">
|
||||
<os name="OpenBSD"/>
|
||||
</condition>
|
||||
<property name="grep" value="grep"/>
|
||||
<apply dir="${build.native}" executable="${grep}" parallel="true"
|
||||
failonerror="true" relative="true" output="${md5.file}">
|
||||
@@ -207,7 +252,10 @@
|
||||
<fixcrlf srcdir="${build.native}" includes="sig" eol="unix"/>
|
||||
<checksum property="md5" file="${md5.file}" />
|
||||
<condition property="jni.valid" value="true">
|
||||
<equals arg1="${jni.md5}" arg2="${md5}" trim="true"/>
|
||||
<or>
|
||||
<equals arg1="${jni.md5}" arg2="${md5}" trim="true"/>
|
||||
<equals arg1="${jni.md5}" arg2=""/>
|
||||
</or>
|
||||
</condition>
|
||||
</target>
|
||||
|
||||
@@ -216,10 +264,12 @@
|
||||
<echo>Invalidating native code, new checksum is ${md5}</echo>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/darwin.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/win32-x86.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/win32-amd64.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/linux-i386.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/linux-amd64.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/freebsd-i386.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/freebsd-amd64.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/openbsd-i386.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-x86.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-amd64.jar" overwrite="true"/>
|
||||
<copy file="${dist}/out-of-date.jar" tofile="${dist}/sunos-sparc.jar" overwrite="true"/>
|
||||
@@ -267,12 +317,7 @@
|
||||
file="native/Makefile" byline="true"/>
|
||||
<!-- ensure ARCH is set properly for 64-bit capable platforms -->
|
||||
<!-- use ANT_OPTS=-d64 to build 64-bit if not the platform default -->
|
||||
<condition property="ARCH" value="${os.arch}">
|
||||
<or>
|
||||
<os arch="sparcv9"/>
|
||||
<os arch="amd64"/>
|
||||
</or>
|
||||
</condition>
|
||||
<property name="ARCH" value="${os.arch}"/>
|
||||
<condition property="make.CC" value="CC=${CC}" else="IGNORE=">
|
||||
<isset property="CC"/>
|
||||
</condition>
|
||||
@@ -302,7 +347,10 @@
|
||||
<os name="SunOS"/>
|
||||
</condition>
|
||||
<condition property="make" value="gmake">
|
||||
<os name="FreeBSD"/>
|
||||
<or>
|
||||
<os name="FreeBSD"/>
|
||||
<os name="OpenBSD"/>
|
||||
</or>
|
||||
</condition>
|
||||
<!-- Default make program -->
|
||||
<property name="make" value="make"/>
|
||||
@@ -311,6 +359,8 @@
|
||||
<arg value="JAVA_HOME=${jdk.home}"/>
|
||||
<arg value="JAVAH=${build.native}"/>
|
||||
<arg value="DEBUG=${debug.native}"/>
|
||||
<arg value="CFLAGS_EXTRA=${cflags_extra.native}"/>
|
||||
<arg value="DYNAMIC_LIBFFI=${dynlink.native}"/>
|
||||
<arg value="${make.CC}"/>
|
||||
<arg value="${make.BUILD}"/>
|
||||
<arg value="${make.SDKROOT}"/>
|
||||
@@ -321,13 +371,13 @@
|
||||
</exec>
|
||||
<mkdir dir="${classes}/com/sun/jna/${os.prefix}"/>
|
||||
<copy todir="${classes}/com/sun/jna/${os.prefix}">
|
||||
<fileset dir="${build.native}"
|
||||
<fileset dir="${build.native}"
|
||||
includes="jnidispatch.dll,libjnidispatch.*"/>
|
||||
</copy>
|
||||
<mkdir dir="${eclipse.classes}/com/sun/jna/${os.prefix}"/>
|
||||
<copy todir="${eclipse.classes}/com/sun/jna/${os.prefix}"
|
||||
failonerror="false">
|
||||
<fileset dir="${build.native}"
|
||||
<fileset dir="${build.native}"
|
||||
includes="jnidispatch.dll,libjnidispatch.*"/>
|
||||
</copy>
|
||||
<!-- For web start, native libraries may be provided in the root of -->
|
||||
@@ -353,7 +403,7 @@
|
||||
</target>
|
||||
|
||||
<!-- When running tests from an IDE, be sure to set jna.library.path -->
|
||||
<!-- to where the test library (testlib) is found -->
|
||||
<!-- to where the test library (testlib) is found. -->
|
||||
<target name="test" depends="jar,examples,compile-tests"
|
||||
description="Run all unit tests">
|
||||
<property name="test.fork" value="yes"/>
|
||||
@@ -361,28 +411,36 @@
|
||||
<property name="results.junit" location="${build}/junit-results"/>
|
||||
<mkdir dir="${results.junit}"/>
|
||||
<echo>Saving test results in ${results.junit}</echo>
|
||||
<property name="tests.stdcall" value="**/win32/*StdCallTest.java"/>
|
||||
<condition property="tests.platform" value="**/win32/*Test.java">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
<condition property="tests.exclude" value="**/win32/*StdCallTest.java">
|
||||
<and><os family="windows"/><not><os arch="x86"/></not></and>
|
||||
</condition>
|
||||
<condition property="tests.platform" value="**/unix/*Test.java">
|
||||
<and>
|
||||
<os family="unix"/>
|
||||
<not><os family="mac"/></not>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="vm.arch" value="-d64">
|
||||
<or>
|
||||
<and><os family="mac"/>
|
||||
<or><os arch="x86_64"/><os arch="ppc64"/></or>
|
||||
</and>
|
||||
<os arch="sparcv9"/>
|
||||
</or>
|
||||
<condition property="vmopt.arch" value="-d64" else="-Dignore">
|
||||
<and>
|
||||
<!-- Sun 64-bit VM for windows doesn't support the -d64 switch -->
|
||||
<not><os family="windows"/></not>
|
||||
<equals arg1="${vm.arch}" arg2="-d64" trim="true"/>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="vm.arch" value="-Dignore"/>
|
||||
<property name="tests.platform" value=""/>
|
||||
<property name="tests.exclude" value=""/>
|
||||
<junit printsummary="yes" fork="${test.fork}" failureproperty="testfailure">
|
||||
<!-- avoid VM conflicts with JNA protected mode -->
|
||||
<env key="${ld.preload}" file="${libjsig}"/>
|
||||
<jvmarg value="-Djna.library.path=${build.native}"/>
|
||||
<jvmarg value="${vm.arch}"/>
|
||||
<!-- Avoid VM crashes, if possible -->
|
||||
<jvmarg value="-Djna.protected=true"/>
|
||||
<jvmarg value="-Djna.builddir=${build}"/>
|
||||
<jvmarg value="${vmopt.arch}"/>
|
||||
<classpath><path refid="test.runpath"/></classpath>
|
||||
<formatter type="xml"/>
|
||||
<batchtest todir="${results.junit}">
|
||||
@@ -405,18 +463,10 @@
|
||||
</target>
|
||||
|
||||
<target name="with.clover" description="Enable code coverage for tests">
|
||||
<taskdef resource="clovertasks"/>
|
||||
<taskdef resource="cloverlib.xml" classpath="lib/clover.jar"/>
|
||||
<property name="clover" value="true"/>
|
||||
<property name="build" value="build.clover"/>
|
||||
<property name="clover.include" value="**/*.java"/>
|
||||
<property name="clover.exclude" value="**/examples/**/*.java"/>
|
||||
<property name="tests.exclude" value="${clover.exclude}"/>
|
||||
<clover-setup initString="${build}/coverage.db">
|
||||
<fileset dir="${src}">
|
||||
<include name="${clover.include}"/>
|
||||
<exclude name="${clover.exclude}"/>
|
||||
</fileset>
|
||||
</clover-setup>
|
||||
<clover-setup/>
|
||||
</target>
|
||||
|
||||
<target name="clover" depends="with.clover,test"
|
||||
@@ -425,6 +475,8 @@
|
||||
<mkdir dir="${reports.clover}"/>
|
||||
<clover-report>
|
||||
<current outfile="${reports.clover}" title="clover">
|
||||
<fileset dir="." includes="**/*.java" excludes="**/examples/**/*.java"/>
|
||||
<testresults dir="${results.junit}" includes="TEST-*.xml"/>
|
||||
<format type="html"/>
|
||||
</current>
|
||||
</clover-report>
|
||||
@@ -471,13 +523,15 @@
|
||||
description="Build distribution files">
|
||||
<jar jarfile="${dist}/jna.jar" duplicate="preserve">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Title" value="${impl.title}"/>
|
||||
<attribute name="Implementation-Vendor" value="${vendor}"/>
|
||||
<attribute name="Implementation-Version" value="${impl.version}"/>
|
||||
<attribute name="Specification-Title" value="${spec.title}"/>
|
||||
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
|
||||
<attribute name="Specification-Version" value="${spec.version}"/>
|
||||
<attribute name="Main-Class" value="com.sun.jna.Native"/>
|
||||
<section name="com/sun/jna/">
|
||||
<attribute name="Implementation-Title" value="${impl.title}"/>
|
||||
<attribute name="Implementation-Vendor" value="${vendor}"/>
|
||||
<attribute name="Implementation-Version" value="${impl.version}"/>
|
||||
<attribute name="Specification-Title" value="${spec.title}"/>
|
||||
<attribute name="Specification-Vendor" value="${spec.vendor}"/>
|
||||
<attribute name="Specification-Version" value="${spec.version}"/>
|
||||
</section>
|
||||
</manifest>
|
||||
<zipfileset src="${build}/${jar}"/>
|
||||
<zipfileset src="${dist}/win32-x86.jar"
|
||||
@@ -510,6 +564,12 @@
|
||||
<zipfileset src="${dist}/freebsd-amd64.jar"
|
||||
includes="*jnidispatch*"
|
||||
prefix="com/sun/jna/freebsd-amd64"/>
|
||||
<zipfileset src="${dist}/openbsd-i386.jar"
|
||||
includes="*jnidispatch*"
|
||||
prefix="com/sun/jna/openbsd-i386"/>
|
||||
<zipfileset src="${dist}/win32-amd64.jar"
|
||||
includes="*jnidispatch*"
|
||||
prefix="com/sun/jna/win32-amd64"/>
|
||||
</jar>
|
||||
<copy todir="${dist}">
|
||||
<fileset dir="${build}">
|
||||
@@ -520,11 +580,24 @@
|
||||
<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>
|
||||
<!-- Sources package as required by maven -->
|
||||
<zip zipfile="${dist}/src-mvn.zip">
|
||||
<zipfileset dir="${src}" includes="**/*.jar,**/*.html,**/*.png"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
Copyright (c) 2008 Stefan Endrullis, All Rights Reserved
|
||||
|
||||
Disclaimer:
|
||||
===========
|
||||
This code 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 code 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.
|
||||
|
||||
|
||||
Description:
|
||||
============
|
||||
|
||||
The intension of this contribution is to provide an object oriented
|
||||
interface to X11. It doesn't not cover all available X11 functions, but
|
||||
it supports major functions to manage the X11 desktop, windows and keys.
|
||||
|
||||
If you want to help to extend this API, you're welcome!
|
||||
|
||||
|
||||
Project structure:
|
||||
==================
|
||||
|
||||
The project has been divided into two parts:
|
||||
- jnacontrib.x11.api
|
||||
- jnacontrib.c11.demos
|
||||
|
||||
The first part contains the API files. The main class is the class X.
|
||||
The second part contains some demos showing you how you can use the API.
|
||||
|
||||
X.java:
|
||||
-------
|
||||
Object oriented interface to X11. It mainly contains methods related
|
||||
to window management but also some functions for keys.
|
||||
Static methods for getting information about Win32 accounts (users
|
||||
and groups).
|
||||
- list all domain users
|
||||
- list all domain groups
|
||||
- list all local or domain groups where a user belongs to
|
||||
- get account by SID
|
||||
- get SID of account
|
||||
- get domain controller name
|
||||
- get domain name
|
||||
|
||||
X11KeySymDef.java
|
||||
-----------------
|
||||
Class X11KeySymDef is a Java translation of keysymdef.h and contains all
|
||||
KeySym definitions of the X server.
|
||||
|
||||
XDesktopDemo.java
|
||||
-----------------
|
||||
Class XDesktopDemo is a small demonstration of the window management
|
||||
capabilities of X. It's a GUI which allows you to move windows to other
|
||||
desktops, switch to other desktops, hide all windows etc.
|
||||
|
||||
XTestDemo.java
|
||||
--------------
|
||||
This class demonstrates how you can use the "Test extension" of the X
|
||||
server, which allows you to simulate key and mouse events. Be careful
|
||||
when running the program, because it simulates keystrokes and "types"
|
||||
the words "hello world" in the active window.
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="jnacontrib.x11" default="jar" basedir=".">
|
||||
<description>Builds, tests, and runs the project jnacontrib.x11.</description>
|
||||
<!-- Locations -->
|
||||
<property name="src" location="src"/>
|
||||
<property name="build" location="build"/>
|
||||
<property name="jna-src" location="../../src"/>
|
||||
<property name="jna-dist" location="../../dist"/>
|
||||
|
||||
<property name="buildClasses" location="${build}/classes"/>
|
||||
<property name="buildJar" location="${build}/jnacontrib-x11.jar"/>
|
||||
|
||||
<path id="classpath">
|
||||
<fileset dir="../../dist">
|
||||
<include name="jna.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<!-- Run XDesktopDemo. -->
|
||||
<target name="runXDesktopDemo" depends="compile">
|
||||
<java classname="jnacontrib.x11.demos.XDesktopDemo" fork="true">
|
||||
<classpath>
|
||||
<pathelement location="${buildClasses}" />
|
||||
<path refid="classpath"/>
|
||||
</classpath>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<!-- Run XTestDemo. -->
|
||||
<target name="runXTestDemo" depends="compile">
|
||||
<java classname="jnacontrib.x11.demos.XTestDemo" fork="true">
|
||||
<classpath>
|
||||
<pathelement location="${buildClasses}" />
|
||||
<path refid="classpath"/>
|
||||
</classpath>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<!-- Delete class and jar files. -->
|
||||
<target name="clean">
|
||||
<delete dir="${buildClasses}"/>
|
||||
<delete file="${buildJar}"/>
|
||||
<delete dir="${build}"/>
|
||||
</target>
|
||||
|
||||
<!-- Compile all classes. -->
|
||||
<target name="compile">
|
||||
<mkdir dir="${buildClasses}"/>
|
||||
|
||||
<!-- Compile the project. -->
|
||||
<javac srcdir="${src}" destdir="${buildClasses}" target="1.5" source="1.5" encoding="UTF-8" debug="on">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
</classpath>
|
||||
<src>
|
||||
<dirset dir="${src}"/>
|
||||
<dirset dir="${jna-src}/com/sun/jna/examples/unix"/>
|
||||
</src>
|
||||
</javac>
|
||||
|
||||
<!-- Copy all non-java files to classes. -->
|
||||
<copy todir="${buildClasses}">
|
||||
<fileset dir="src">
|
||||
<exclude name="**/*.java"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!-- Create jar-file. -->
|
||||
<target name="jar" depends="compile">
|
||||
<jar jarfile="${buildJar}" basedir="${buildClasses}">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="jnacontrib.x11.demos.XDesktopDemo"/>
|
||||
<attribute name="Class-Path" value="${jna-dist}/jna.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
</project>
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,365 @@
|
||||
/* Copyright (c) 2008 Stefan Endrullis, 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 jnacontrib.x11.demos;
|
||||
|
||||
import jnacontrib.x11.api.X;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.TableModel;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Demonstrates some possibilities on your X Window System.
|
||||
*
|
||||
* @author Stefan Endrullis
|
||||
*/
|
||||
public class XDesktopDemo extends JFrame {
|
||||
public static void main(String[] args) throws X.X11Exception {
|
||||
new XDesktopDemo();
|
||||
}
|
||||
|
||||
private X.Display display = new X.Display();
|
||||
private JList desktopList;
|
||||
private JTable windowTable;
|
||||
private JButton refreshButton;
|
||||
private JButton moveWindowToDesktopButton;
|
||||
private JButton goToDesktopButton;
|
||||
private JButton moveWindowAndGoToDesktopButton;
|
||||
private JButton closeWindowButton;
|
||||
private JButton goToWindowButton;
|
||||
private JButton showDesktop;
|
||||
|
||||
public XDesktopDemo() throws X.X11Exception {
|
||||
super("XDesktopDemo");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
initGui();
|
||||
|
||||
refreshDesktopsAndWindows();
|
||||
|
||||
pack();
|
||||
addListeners();
|
||||
setVisible(true);
|
||||
|
||||
printWmInfo();
|
||||
}
|
||||
|
||||
private void printWmInfo() throws X.X11Exception {
|
||||
X.Window wm = display.getWindowManagerInfo();
|
||||
System.out.println("wm.getTitle() = " + wm.getTitle());
|
||||
System.out.println("wm.getWindowClass() = " + wm.getWindowClass());
|
||||
System.out.println("wm.getPID() = " + wm.getPID());
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
refreshButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
try {
|
||||
refreshDesktopsAndWindows();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
goToDesktopButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
int desktopNr = desktopList.getSelectedIndex();
|
||||
if (desktopNr >= 0) {
|
||||
try {
|
||||
display.switchDesktop(desktopNr);
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
goToWindowButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
X.Window window = getSelectedWindow();
|
||||
try {
|
||||
window.activate();
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
showDesktop.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
try {
|
||||
display.showingDesktop(true);
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
moveWindowToDesktopButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
X.Window window = getSelectedWindow();
|
||||
try {
|
||||
window.moveToDesktop(desktopList.getSelectedIndex());
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
moveWindowAndGoToDesktopButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
X.Window window = getSelectedWindow();
|
||||
try {
|
||||
window.moveToDesktop(desktopList.getSelectedIndex());
|
||||
window.activate();
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
closeWindowButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
X.Window window = getSelectedWindow();
|
||||
try {
|
||||
window.close();
|
||||
display.flush();
|
||||
} catch (X.X11Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private X.Window getSelectedWindow() {
|
||||
WindowTableModel tableModel = (WindowTableModel) windowTable.getModel();
|
||||
return tableModel.getWindow(windowTable.getSelectedRow());
|
||||
}
|
||||
|
||||
private void refreshDesktopsAndWindows() throws X.X11Exception {
|
||||
// update desktop list
|
||||
X.Desktop[] desktops = display.getDesktops();
|
||||
ArrayList list = new ArrayList(desktops.length);
|
||||
for (int i = 0; i < desktops.length; i++) {
|
||||
list.add(desktops[i].name);
|
||||
}
|
||||
desktopList.clearSelection();
|
||||
desktopList.setModel(new SimpleListModel(list));
|
||||
|
||||
// select active desktop
|
||||
int activeDesktop = display.getActiveDesktopNumber();
|
||||
desktopList.setSelectedIndex(activeDesktop);
|
||||
|
||||
// update window list
|
||||
int activeWindowId = display.getActiveWindow().getID();
|
||||
int activeWindowNumber = -1;
|
||||
X.Window[] windows = display.getWindows();
|
||||
String[] head = new String[]{
|
||||
"ID", "Desktop", "Title",
|
||||
"X", "Y", "Width", "Height"
|
||||
};
|
||||
String[][] data = new String[windows.length][head.length];
|
||||
for (int i = 0; i < windows.length; i++) {
|
||||
X.Window window = windows[i];
|
||||
X.Window.Geometry geo = window.getGeometry();
|
||||
int windowId = window.getID();
|
||||
data[i][0] = String.format("0x%08X", new Object[]{new Integer(windowId)});
|
||||
data[i][1] = "" + window.getDesktop();
|
||||
data[i][2] = window.getTitle();
|
||||
data[i][3] = "" + geo.x;
|
||||
data[i][4] = "" + geo.y;
|
||||
data[i][5] = "" + geo.width;
|
||||
data[i][6] = "" + geo.height;
|
||||
if (windowId == activeWindowId) {
|
||||
activeWindowNumber = i;
|
||||
}
|
||||
}
|
||||
windowTable.setModel(new WindowTableModel(head, data, windows));
|
||||
if (activeWindowNumber >= 0) {
|
||||
windowTable.getSelectionModel().setSelectionInterval(activeWindowNumber, activeWindowNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void initGui() {
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new GridBagLayout());
|
||||
final JPanel panel1 = new JPanel();
|
||||
panel1.setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbc;
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 0.8;
|
||||
gbc.weighty = 1.0;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
mainPanel.add(panel1, gbc);
|
||||
panel1.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), "Desktops"));
|
||||
desktopList = new JList();
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 1.0;
|
||||
gbc.weighty = 1.0;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
panel1.add(desktopList, gbc);
|
||||
final JPanel panel2 = new JPanel();
|
||||
panel2.setLayout(new GridBagLayout());
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 1.0;
|
||||
gbc.weighty = 1.0;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
mainPanel.add(panel2, gbc);
|
||||
panel2.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), "Windows"));
|
||||
final JScrollPane scrollPane1 = new JScrollPane();
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 1.0;
|
||||
gbc.weighty = 1.0;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
panel2.add(scrollPane1, gbc);
|
||||
windowTable = new JTable();
|
||||
windowTable.setEnabled(true);
|
||||
scrollPane1.setViewportView(windowTable);
|
||||
final JPanel panel3 = new JPanel();
|
||||
panel3.setLayout(new GridBagLayout());
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
gbc.gridwidth = 2;
|
||||
gbc.weightx = 1.0;
|
||||
gbc.weighty = 1.0;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
mainPanel.add(panel3, gbc);
|
||||
panel3.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), "Actions"));
|
||||
goToDesktopButton = new JButton();
|
||||
goToDesktopButton.setText("go to desktop");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
gbc.gridwidth = 1;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(goToDesktopButton, gbc);
|
||||
refreshButton = new JButton();
|
||||
refreshButton.setText("refresh");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(refreshButton, gbc);
|
||||
goToWindowButton = new JButton();
|
||||
goToWindowButton.setText("go to window");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(goToWindowButton, gbc);
|
||||
moveWindowAndGoToDesktopButton = new JButton();
|
||||
moveWindowAndGoToDesktopButton.setText("move window and go to desktop");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 2;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(moveWindowAndGoToDesktopButton, gbc);
|
||||
closeWindowButton = new JButton();
|
||||
closeWindowButton.setText("close window");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 3;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(closeWindowButton, gbc);
|
||||
moveWindowToDesktopButton = new JButton();
|
||||
moveWindowToDesktopButton.setText("move window to desktop");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 1;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(moveWindowToDesktopButton, gbc);
|
||||
showDesktop = new JButton();
|
||||
showDesktop.setText("show desktop");
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 0;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel3.add(showDesktop, gbc);
|
||||
|
||||
// more attributes
|
||||
desktopList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
windowTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
setContentPane(mainPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple ListModel managing a list of objects.
|
||||
*/
|
||||
public static class SimpleListModel extends AbstractListModel {
|
||||
private ArrayList list;
|
||||
|
||||
public SimpleListModel(ArrayList list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public int getSize() { return list.size(); }
|
||||
public Object getElementAt(int i) { return list.get(i); }
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple TableModel managing an array of Strings.
|
||||
*/
|
||||
public static class WindowTableModel implements TableModel {
|
||||
private String[] head;
|
||||
private String[][] data;
|
||||
private X.Window[] windows;
|
||||
|
||||
public WindowTableModel(String[] head, String[][] data, X.Window[] windows) {
|
||||
this.head = head;
|
||||
this.data = data;
|
||||
this.windows = windows;
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return data.length;
|
||||
}
|
||||
public int getColumnCount() {
|
||||
return head.length;
|
||||
}
|
||||
public String getColumnName(int columnIndex) {
|
||||
return head[columnIndex];
|
||||
}
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
return String.class;
|
||||
}
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false;
|
||||
}
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return data[rowIndex][columnIndex];
|
||||
}
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
}
|
||||
public void addTableModelListener(TableModelListener l) {
|
||||
}
|
||||
public void removeTableModelListener(TableModelListener l) {
|
||||
}
|
||||
|
||||
public X.Window getWindow(int rowIndex) {
|
||||
return windows[rowIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 2008 Stefan Endrullis, 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 jnacontrib.x11.demos;
|
||||
|
||||
import jnacontrib.x11.api.X;
|
||||
import com.sun.jna.examples.unix.X11;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.NativeLong;
|
||||
|
||||
/**
|
||||
* Demonstration of the X extension XTest.
|
||||
*/
|
||||
public class XTestDemo {
|
||||
private static final long DELAY = 20;
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
new XTestDemo();
|
||||
}
|
||||
|
||||
private X.Display display = new X.Display();
|
||||
|
||||
public XTestDemo() throws InterruptedException {
|
||||
IntByReference event_basep = new IntByReference();
|
||||
IntByReference error_basep = new IntByReference();
|
||||
IntByReference majorp = new IntByReference();
|
||||
IntByReference minorp = new IntByReference();
|
||||
|
||||
if (X11.XTest.INSTANCE.XTestQueryExtension(
|
||||
display.getX11Display(),
|
||||
event_basep,
|
||||
error_basep,
|
||||
majorp,
|
||||
minorp)) {
|
||||
|
||||
System.out.println("event_basep.getValue() = " + event_basep.getValue());
|
||||
System.out.println("error_basep.getValue() = " + error_basep.getValue());
|
||||
System.out.println("majorp.getValue() = " + majorp.getValue());
|
||||
System.out.println("minorp.getValue() = " + minorp.getValue());
|
||||
}
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
type("hello world");
|
||||
// typeKey("Return");
|
||||
// type("it works!");
|
||||
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
private void type(String text) {
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
char myChar = text.charAt(i);
|
||||
|
||||
// get keycode from character
|
||||
switch (myChar) {
|
||||
case ' ': typeKey(65); break;
|
||||
default: typeKey("" + myChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void typeKey(String keyName) {
|
||||
X11.KeySym keysym = X11.INSTANCE.XStringToKeysym(keyName);
|
||||
typeKey(X11.INSTANCE.XKeysymToKeycode(display.getX11Display(), keysym));
|
||||
}
|
||||
|
||||
private void typeKey(int keyCode) {
|
||||
if (keyCode == -1) return;
|
||||
|
||||
// press key
|
||||
X11.XTest.INSTANCE.XTestFakeKeyEvent(display.getX11Display(), keyCode, true, new NativeLong(DELAY));
|
||||
X11.INSTANCE.XFlush(display.getX11Display());
|
||||
// release key
|
||||
X11.XTest.INSTANCE.XTestFakeKeyEvent(display.getX11Display(), keyCode, false, new NativeLong(DELAY));
|
||||
X11.INSTANCE.XFlush(display.getX11Display());
|
||||
}
|
||||
}
|
||||
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -0,0 +1,5 @@
|
||||
nQMpVtdkeiLDhkfVhlebsGWVMnsDeqDAmHuaUJSRUxwraf
|
||||
mi2K4SaejnjOrPDIm3nJq8<b2Ke>wQwCu3>RYeCLGxFda>
|
||||
PRoQxwONRmmnMpmQRPQvuNmQoQpMQRMpOnSSTxXMvwWmvu
|
||||
VtqwVvXwqqRnmqmUUnnvuvvqqmmmmmUUnnvuvvqqmmmmmU
|
||||
UgkXkabskgXsXkkbqUUnmm
|
||||
+91
-53
@@ -10,10 +10,10 @@
|
||||
# Supported platforms (built and tested):
|
||||
#
|
||||
# Windows 2000/XP/2003/Vista (x86)
|
||||
# OS X (i386/ppc)
|
||||
# Linux (i386, amd64)
|
||||
# Solaris (i386, sparc, sparcv9)
|
||||
# FreeBSD (i386)
|
||||
# Darwin/OS X (i386/x86_64/ppc)
|
||||
# Linux (i386/amd64)
|
||||
# Solaris (i386/amd64/sparc/sparcv9)
|
||||
# FreeBSD (i386/amd64)
|
||||
#
|
||||
|
||||
# Systems which support POSIX signals may be able to support VM crash
|
||||
@@ -23,34 +23,40 @@
|
||||
OS=$(shell uname | sed -e 's/\(CYGWIN\|MINGW32\).*/win32/g' \
|
||||
-e 's/SunOS.*/solaris/g' \
|
||||
-e 's/FreeBSD.*/freebsd/g' \
|
||||
-e 's/OpenBSD.*/openbsd/g' \
|
||||
-e 's/Darwin.*/darwin/g' \
|
||||
-e 's/Linux.*/linux/g')
|
||||
|
||||
VERSION=3.0.3 # auto-generated by ant
|
||||
CHECKSUM=892beacd437514d23ed9b1cefeb2ead6 # auto-generated by ant
|
||||
VERSION=3.1.0 # auto-generated by ant
|
||||
CHECKSUM=816e53324203bcffe46f43e482e5c286 # auto-generated by ant
|
||||
|
||||
JAVA_INCLUDES=-I"$(JAVA_HOME)/include" \
|
||||
-I"$(JAVA_HOME)/include/$(OS)"
|
||||
|
||||
LIBDIR=$(JAVA_HOME)/jre/lib/$(ARCH)
|
||||
BUILD=../build/native
|
||||
JAVAH=$(BUILD)
|
||||
INSTALLDIR=../build/$(OS)
|
||||
JNIDISPATCH_OBJS=$(BUILD)/dispatch.o $(BUILD)/callback.o $(EXTRAOBJS)
|
||||
RSRC=$(BUILD)/rsrc.o
|
||||
ifneq ($(DYNAMIC_LIBFFI),true)
|
||||
FFI_SRC=$(shell pwd)/libffi
|
||||
FFI_BUILD=$(BUILD)/libffi
|
||||
FFI_LIB=$(FFI_BUILD)/.libs/libffi_convenience.a
|
||||
FFI_CONFIG=--disable-static --with-pic=yes
|
||||
FFI_LIB=$(FFI_BUILD)/.libs/libffi$(ARSFX)
|
||||
FFI_ENV=CC="$(CC)" CFLAGS="$(CDEBUG)" CPPFLAGS="$(CDEFINES)"
|
||||
FFI_CONFIG=--enable-static --disable-shared --with-pic=yes
|
||||
endif
|
||||
LIBRARY=$(BUILD)/$(LIBPFX)jnidispatch$(JNISFX)
|
||||
TESTLIB=$(BUILD)/$(LIBPFX)testlib$(LIBSFX)
|
||||
TESTLIB2=$(BUILD)/$(LIBPFX)testlib2$(LIBSFX)
|
||||
|
||||
# Reasonable defaults based on GCC
|
||||
LIBPFX=lib
|
||||
LIBSFX=.so
|
||||
ARSFX=.a
|
||||
JNISFX=$(LIBSFX)
|
||||
CC=gcc
|
||||
LD=gcc
|
||||
LIBS=
|
||||
# Default to Sun recommendations for JNI compilation
|
||||
#COPT=-O2 -fomit-frame-pointer
|
||||
COPT=-fno-omit-frame-pointer -fno-strict-aliasing
|
||||
@@ -58,14 +64,21 @@ CASM=-S
|
||||
ifeq ($(DEBUG),true)
|
||||
CDEBUG=-g
|
||||
endif
|
||||
CFLAGS_EXTRA=
|
||||
COUT=-o $@
|
||||
CINCLUDES=$(JAVA_INCLUDES) -I"$(JAVAH)" -I$(FFI_BUILD)/include
|
||||
CDEFINES=-D_REENTRANT
|
||||
PCFLAGS=-W -Wall -Wno-unused -Wno-parentheses
|
||||
CFLAGS=$(PCFLAGS) $(COPT) $(CDEBUG) $(CDEFINES) $(CINCLUDES) \
|
||||
CFLAGS=$(PCFLAGS) $(CFLAGS_EXTRA) $(COPT) $(CDEBUG) $(CDEFINES) $(CINCLUDES) \
|
||||
-DVERSION='"$(VERSION)"' -DCHECKSUM='"$(CHECKSUM)"'
|
||||
LDFLAGS=-o $@ -shared
|
||||
ifeq ($(DYNAMIC_LIBFFI),true)
|
||||
CFLAGS += $(shell pkg-config --cflags libffi 2>/dev/null || echo)
|
||||
LIBS += $(shell pkg-config --libs libffi 2>/dev/null || echo -lffi)
|
||||
else
|
||||
# -static-libgcc avoids gcc library incompatibilities across linux systems
|
||||
LDFLAGS=-o $@ -shared -Wl,-soname,$@ -static-libgcc
|
||||
LDFLAGS += -static-libgcc
|
||||
endif
|
||||
# Avoid bug in X11-based 1.5/1.6 VMs; dynamically load instead of linking
|
||||
# See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705
|
||||
#LIBS=-L"$(LIBDIR)" -ljawt
|
||||
@@ -73,51 +86,64 @@ STRIP=strip -x
|
||||
# end defaults
|
||||
|
||||
ifeq ($(OS),win32)
|
||||
# Uncomment this line to use MSVC (doesn't yet work with libffi)
|
||||
#CC=cl
|
||||
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
|
||||
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
|
||||
CDEFINES=-DHAVE_PROTECTION
|
||||
|
||||
ifeq ($(CC),cl)
|
||||
LD=link
|
||||
COPT=-O1 -Op
|
||||
ifeq ($(DEBUG),true)
|
||||
COPT=-Od
|
||||
DBG=d
|
||||
CDEBUG=-D_DEBUG -GZ -Zi
|
||||
endif
|
||||
COUT=-Fo$@
|
||||
PCFLAGS=-nologo -MD$(DBG) -W3 -WX -GX -YX -Fd$(@D)/$* -Fp$(@D)/$*
|
||||
CASM=-FAs
|
||||
|
||||
LDFLAGS=/pdb:$(subst .dll,,$@).pdb /implib:$(subst .dll,,$@).lib /debug /machine:i386 /pdbtype:sept /dll /nologo /opt:REF /incremental:no /out:$@
|
||||
LIBDIR=/libpath:"$(JAVA_HOME)/lib"
|
||||
#LIBS=$(LIBDIR) jawt.lib
|
||||
WINDRES=windres
|
||||
EXTRAOBJS=$(RSRC)
|
||||
STRIP=@echo
|
||||
else
|
||||
PCFLAGS+=-mno-cygwin
|
||||
LDFLAGS+=-mno-cygwin -Wl,--add-stdcall-alias
|
||||
LIBDIR="$(JAVA_HOME)/lib"
|
||||
#LIBS=$(LIBDIR)/jawt.lib
|
||||
endif
|
||||
|
||||
LIBPFX=
|
||||
LIBSFX=.dll
|
||||
EXTRAOBJS=$(RSRC)
|
||||
|
||||
ifeq ($(CC),gcc)
|
||||
CC += -mno-cygwin
|
||||
LD += -mno-cygwin -Wl,--add-stdcall-alias
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),amd64)
|
||||
|
||||
WINDRES=/usr/local/mingw64-cross/bin/x86_64-pc-mingw32-windres
|
||||
|
||||
# Uncomment to enable MINGW64 cross compiler
|
||||
# Last build attempt has too many runtime problems (alloca broken) (080831)
|
||||
#MINGW = x86_64-pc-mingw32-gcc
|
||||
ifneq ($(MINGW),)
|
||||
CC = $(MINGW) -m64 -mno-cygwin
|
||||
LD = $(CC)
|
||||
LDFLAGS=-o $@ -shared
|
||||
LIBS= -lmingwex -lkernel32 -lmsvcrt
|
||||
FFI_CONFIG += --host=x86_64-pc-mingw32
|
||||
else
|
||||
# MSVC (wrapper scripts)
|
||||
CC=$(FFI_SRC)/../cc.sh -m64
|
||||
LD=$(FFI_SRC)/../ld.sh -m64
|
||||
ARSFX=.lib
|
||||
FFI_CONFIG += --host=x86_64-pc-mingw32 && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
|
||||
FFI_ENV += LD="$(LD)" CPP=cpp
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS),linux)
|
||||
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
|
||||
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
|
||||
PCFLAGS+=-fPIC
|
||||
CDEFINES+=-DHAVE_PROTECTION
|
||||
LDFLAGS+=-Wl,-soname,$@
|
||||
endif
|
||||
|
||||
ifeq ($(OS),freebsd)
|
||||
ARCH=$(shell uname -m | sed 's/i[456]86/i386/g')
|
||||
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
|
||||
PCFLAGS+=-fPIC
|
||||
CINCLUDES+=-I/usr/X11R6/include
|
||||
LDFLAGS=-o $@ -shared
|
||||
CDEFINES+=-DHAVE_PROTECTION
|
||||
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
|
||||
endif
|
||||
|
||||
ifeq ($(OS),openbsd)
|
||||
ARCH=$(shell uname -m | sed 's/i.86/i386/g')
|
||||
PCFLAGS+=-fPIC
|
||||
CINCLUDES+=-I/usr/X11R6/include
|
||||
LDFLAGS=-o $@ -shared
|
||||
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
|
||||
endif
|
||||
|
||||
ifeq ($(OS),solaris)
|
||||
@@ -125,21 +151,22 @@ ifeq ($(ARCH),)
|
||||
ARCH=$(shell uname -p)
|
||||
endif
|
||||
PCFLAGS+=-fPIC
|
||||
CDEFINES+=-DHAVE_PROTECTION
|
||||
LDFLAGS=-o $@ -G
|
||||
CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT
|
||||
ifeq ($(ARCH), sparcv9)
|
||||
# alter CC instead of PCFLAGS, since we need to pass it down to libffi
|
||||
# configure and some of the other settings in PCFLAGS might make the build
|
||||
# choke
|
||||
CC += -m64
|
||||
LDFLAGS += -m64
|
||||
LD += -m64
|
||||
endif
|
||||
endif
|
||||
|
||||
# Enable 64-bit builds if the arch demands it
|
||||
ifeq ($(CC),gcc)
|
||||
ifeq ($(ARCH),amd64)
|
||||
CC += -m64
|
||||
LDFLAGS += -m64
|
||||
LD += -m64
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS),darwin)
|
||||
@@ -156,12 +183,12 @@ SYSLIBROOT=-Wl,-syslibroot,$(SDKROOT)
|
||||
ISYSROOT=-isysroot $(SDKROOT)
|
||||
ARCHFLAGS=-arch ppc -arch i386
|
||||
ifneq ($(findstring 10.5,$(SDKROOT)),)
|
||||
ALT_ARCHS+=x86_64 #ppc64
|
||||
ARCHFLAGS+=-arch x86_64 #-arch ppc64
|
||||
ALT_ARCHS+=x86_64
|
||||
ARCHFLAGS+=-arch x86_64
|
||||
endif
|
||||
endif
|
||||
PCFLAGS+=$(ISYSROOT) -x objective-c
|
||||
CDEFINES=-DTARGET_RT_MAC_CFM=0
|
||||
CDEFINES+=-DTARGET_RT_MAC_CFM=0 -DFFI_MMAP_EXEC_WRIT
|
||||
LDFLAGS=$(ARCHFLAGS) -dynamiclib -o $@ -framework JavaVM \
|
||||
-compatibility_version $(shell echo ${VERSION}|sed 's/^\([0-9][0-9]*\).*/\1/g') \
|
||||
-current_version $(VERSION) \
|
||||
@@ -187,27 +214,37 @@ else
|
||||
$(CC) $(CFLAGS) -c $< $(COUT)
|
||||
endif
|
||||
|
||||
all: $(LIBRARY) $(TESTLIB)
|
||||
all: $(LIBRARY) $(TESTLIB) $(TESTLIB2)
|
||||
|
||||
install:
|
||||
mkdir $(INSTALLDIR)
|
||||
cp $(LIBRARY) $(INSTALLDIR)
|
||||
|
||||
$(RSRC): $(BUILD)/jnidispatch.rc
|
||||
windres -i $< -o $@
|
||||
$(WINDRES) -i $< -o $@ \
|
||||
|| (echo > $@.c && $(CC) $(CFLAGS) -c $@.c $(COUT))
|
||||
|
||||
$(LIBRARY): $(JNIDISPATCH_OBJS) $(FFI_LIB)
|
||||
$(LD) $(LDFLAGS) $(JNIDISPATCH_OBJS) $(FFI_LIB) $(LIBS)
|
||||
|
||||
$(TESTLIB): $(BUILD)/testlib.o
|
||||
$(LD) $(LDFLAGS) $< $(TESTDEF)
|
||||
$(LD) $(LDFLAGS) $<
|
||||
|
||||
ifeq ($(ARSFX),.lib)
|
||||
TESTDEP=$(TESTLIB:.dll=.lib)
|
||||
else
|
||||
TESTDEP=$(TESTLIB)
|
||||
endif
|
||||
$(TESTLIB2): $(BUILD)/testlib2.o
|
||||
$(LD) $(LDFLAGS) $< $(TESTDEP)
|
||||
|
||||
ifneq ($(DYNAMIC_LIBFFI),true)
|
||||
$(FFI_LIB):
|
||||
@mkdir -p $(FFI_BUILD)
|
||||
@if [ ! -f $(FFI_BUILD)/Makefile ]; then \
|
||||
echo "Configuring libffi ($(ARCH))"; \
|
||||
(cd $(FFI_BUILD) \
|
||||
&& CC="$(CC) $(CDEBUG)" $(FFI_SRC)/configure $(FFI_CONFIG)); \
|
||||
&& $(FFI_ENV) $(FFI_SRC)/configure $(FFI_CONFIG)); \
|
||||
fi
|
||||
$(MAKE) -C $(FFI_BUILD)
|
||||
ifneq ($(SDKROOT),)
|
||||
@@ -216,7 +253,7 @@ ifneq ($(SDKROOT),)
|
||||
if [ ! -f $(BUILD)/libffi.$$arch/Makefile ]; then \
|
||||
echo "Configuring libffi ($$arch)"; \
|
||||
(cd $(BUILD)/libffi.$$arch \
|
||||
&& CFLAGS="-arch $$arch $(ISYSROOT) $(COPT) $(CDEBUG) $(CDEFINES)" \
|
||||
&& CC="$(CC)" CFLAGS="-arch $$arch $(ISYSROOT) $(COPT) $(CDEBUG)" CPPFLAGS="$(CDEFINES)" \
|
||||
LDFLAGS="-arch $$arch" \
|
||||
$(FFI_SRC)/configure $(FFI_CONFIG) --host=$$arch-apple-darwin --disable-dependency-tracking); \
|
||||
fi; \
|
||||
@@ -225,6 +262,7 @@ ifneq ($(SDKROOT),)
|
||||
/usr/bin/libtool -static -o $@.tmp $(FFI_BUILD)/.libs/${@F} $(BUILD)/libffi.*/.libs/${@F}
|
||||
mv $@.tmp $@
|
||||
endif
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(RM) -rf $(BUILD)
|
||||
|
||||
+89
-35
@@ -40,8 +40,8 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
|
||||
callconv_t calling_convention) {
|
||||
callback* cb;
|
||||
ffi_abi abi = FFI_DEFAULT_ABI;
|
||||
ffi_type* ffi_rtype;
|
||||
ffi_status status;
|
||||
int args_size = 0;
|
||||
jsize argc;
|
||||
JavaVM* vm;
|
||||
char rtype;
|
||||
@@ -64,13 +64,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;
|
||||
}
|
||||
@@ -81,30 +81,39 @@ create_callback(JNIEnv* env, jobject obj, jobject method,
|
||||
throwByName(env, EIllegalArgument, "Unsupported return type");
|
||||
goto failure_cleanup;
|
||||
}
|
||||
status = ffi_prep_cif(&cb->ffi_cif, abi, argc,
|
||||
get_ffi_rtype(env, return_type, rtype),
|
||||
&cb->ffi_args[0]);
|
||||
ffi_rtype = get_ffi_rtype(env, return_type, rtype);
|
||||
if (!ffi_rtype) {
|
||||
throwByName(env, EIllegalArgument, "Error in return type");
|
||||
goto failure_cleanup;
|
||||
}
|
||||
status = ffi_prep_cif(&cb->ffi_cif, abi, argc, ffi_rtype, &cb->ffi_args[0]);
|
||||
|
||||
switch(status) {
|
||||
case FFI_BAD_ABI:
|
||||
sprintf(msg, "Invalid calling convention: %d", (int)calling_convention);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Invalid calling convention: %d", (int)calling_convention);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
case FFI_BAD_TYPEDEF:
|
||||
sprintf(msg, "Invalid structure definition (native typedef error)");
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Invalid structure definition (native typedef error)");
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
case FFI_OK:
|
||||
ffi_prep_closure_loc(cb->ffi_closure, &cb->ffi_cif, callback_dispatch, cb,
|
||||
cb->x_closure);
|
||||
|
||||
return cb;
|
||||
default:
|
||||
sprintf(msg, "Native callback setup failure: error code %d", status);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Native callback setup failure: error code %d", status);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
failure_cleanup:
|
||||
free_callback(env, cb);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
void
|
||||
@@ -114,15 +123,74 @@ free_callback(JNIEnv* env, callback *cb) {
|
||||
free(cb);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_exception(JNIEnv* env, jobject cb, jthrowable throwable) {
|
||||
#define HANDLER_TYPE "com/sun/jna/Callback$UncaughtExceptionHandler"
|
||||
#define HANDLER_SIG "Lcom/sun/jna/Callback$UncaughtExceptionHandler;"
|
||||
jclass classHandler = (*env)->FindClass(env, HANDLER_TYPE);
|
||||
if (classHandler) {
|
||||
jclass classNative = (*env)->FindClass(env, "com/sun/jna/Native");
|
||||
if (classNative) {
|
||||
jfieldID fid = (*env)->GetStaticFieldID(env, classNative, "callbackExceptionHandler", HANDLER_SIG);
|
||||
if (fid) {
|
||||
jobject handler = (*env)->GetStaticObjectField(env, classNative, fid);
|
||||
if (handler) {
|
||||
jmethodID mid = (*env)->GetMethodID(env, classHandler, "uncaughtException", "(Lcom/sun/jna/Callback;Ljava/lang/Throwable;)V");
|
||||
if (mid) {
|
||||
if (!(*env)->IsSameObject(env, handler, NULL)) {
|
||||
(*env)->CallVoidMethod(env, handler, mid, cb, throwable);
|
||||
}
|
||||
return (*env)->ExceptionCheck(env) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(*env)->ExceptionDescribe(env);
|
||||
(*env)->ExceptionClear(env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
callback_invoke(JNIEnv* env, callback *cb, ffi_cif* cif, void *resp, void **cbargs) {
|
||||
jobject self;
|
||||
|
||||
self = (*env)->NewLocalRef(env, cb->object);
|
||||
// Avoid calling back to a GC'd object
|
||||
if ((*env)->IsSameObject(env, self, NULL)) {
|
||||
fprintf(stderr, "JNA: callback object has been garbage collected\n");
|
||||
memset(resp, 0, cif->rtype->size);
|
||||
}
|
||||
else {
|
||||
jobject result;
|
||||
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);
|
||||
}
|
||||
result = (*env)->CallObjectMethod(env, self, cb->methodID, array);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
jthrowable throwable = (*env)->ExceptionOccurred(env);
|
||||
(*env)->ExceptionClear(env);
|
||||
if (!handle_exception(env, self, throwable)) {
|
||||
fprintf(stderr, "JNA: error handling callback exception, continuing\n");
|
||||
}
|
||||
memset(resp, 0, cif->rtype->size);
|
||||
}
|
||||
else {
|
||||
extract_value(env, result, resp, cif->rtype->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
|
||||
callback* cb = (callback *) user_data;
|
||||
JavaVM* jvm = cb->vm;
|
||||
jobject self;
|
||||
JavaVM* jvm = ((callback *)user_data)->vm;
|
||||
JNIEnv* env;
|
||||
int attached;
|
||||
unsigned int i;
|
||||
jobjectArray array;
|
||||
|
||||
attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
|
||||
if (!attached) {
|
||||
@@ -132,28 +200,14 @@ callback_dispatch(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
|
||||
}
|
||||
}
|
||||
|
||||
self = (*env)->NewLocalRef(env, cb->object);
|
||||
// Avoid calling back to a GC'd object
|
||||
if ((*env)->IsSameObject(env, self, NULL)) {
|
||||
fprintf(stderr, "JNA: callback object has been garbage collected\n");
|
||||
memset(resp, 0, cif->rtype->size);
|
||||
}
|
||||
else {
|
||||
jobject result;
|
||||
array = (*env)->NewObjectArray(env, cif->nargs, classObject, NULL);
|
||||
for (i=0;i < cif->nargs;i++) {
|
||||
jobject arg = new_object(env, cb->param_jtypes[i], cbargs[i]);
|
||||
(*env)->SetObjectArrayElement(env, array, i, arg);
|
||||
}
|
||||
result = (*env)->CallObjectMethod(env, self, cb->methodID, array);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
fprintf(stderr, "JNA: uncaught exception in callback, continuing\n");
|
||||
memset(resp, 0, cif->rtype->size);
|
||||
}
|
||||
else {
|
||||
extract_value(env, result, resp, cif->rtype->size);
|
||||
}
|
||||
// Give the callback its own local frame to ensure all local references
|
||||
// are properly disposed
|
||||
if ((*env)->PushLocalFrame(env, 16) < 0) {
|
||||
fprintf(stderr, "JNA: Out of memory: Can't allocate local frame");
|
||||
return;
|
||||
}
|
||||
callback_invoke(env, (callback *)user_data, cif, resp, cbargs);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
if (!attached) {
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
|
||||
Arquivo executável
+147
@@ -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
|
||||
+262
-90
@@ -22,6 +22,9 @@
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#ifdef _MSC_VER
|
||||
@@ -31,7 +34,14 @@
|
||||
#endif
|
||||
#define LIBNAMETYPE wchar_t*
|
||||
#define LIBNAME2CSTR(ENV,JSTR) newWideCString(ENV,JSTR)
|
||||
#define LOAD_LIBRARY(NAME) LoadLibraryW(NAME)
|
||||
/* See http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx:
|
||||
* "Note that the standard search strategy and the alternate search strategy
|
||||
* specified by LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH differ in
|
||||
* just one way: The standard search begins in the calling application's
|
||||
* directory, and the alternate search begins in the directory of the
|
||||
* executable module that LoadLibraryEx is loading."
|
||||
*/
|
||||
#define LOAD_LIBRARY(NAME) LoadLibraryExW(NAME, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||
#define LOAD_ERROR(BUF,LEN) w32_format_error(BUF, LEN)
|
||||
#define FREE_LIBRARY(HANDLE) FreeLibrary(HANDLE)
|
||||
#define FIND_ENTRY(HANDLE, NAME) GetProcAddress(HANDLE, NAME)
|
||||
@@ -39,8 +49,8 @@
|
||||
#define SET_LAST_ERROR(CODE) SetLastError(CODE)
|
||||
static char*
|
||||
w32_format_error(char* buf, int len) {
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
||||
0, buf, len, NULL);
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
||||
0, buf, len, NULL);
|
||||
return buf;
|
||||
}
|
||||
#else
|
||||
@@ -52,8 +62,8 @@ w32_format_error(char* buf, int len) {
|
||||
#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_LIBRARY(NAME) dlopen(NAME, RTLD_LAZY|RTLD_GLOBAL)
|
||||
#define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF)
|
||||
#define FREE_LIBRARY(HANDLE) dlclose(HANDLE)
|
||||
#define FIND_ENTRY(HANDLE, NAME) dlsym(HANDLE, NAME)
|
||||
#define GET_LAST_ERROR() errno
|
||||
@@ -81,9 +91,9 @@ w32_format_error(char* buf, int len) {
|
||||
|
||||
#ifdef HAVE_PROTECTION
|
||||
static int _protect;
|
||||
#undef PROTECT
|
||||
#define PROTECT _protect
|
||||
#endif
|
||||
#include "protect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -91,9 +101,6 @@ extern "C"
|
||||
|
||||
static jboolean preserve_last_error;
|
||||
|
||||
#define ON_ERROR() throwByName(env, EError, "Invalid memory access")
|
||||
#define PSTART() PROTECTED_START()
|
||||
#define PEND() PROTECTED_END(ON_ERROR())
|
||||
#define MEMCPY(D,S,L) do { \
|
||||
PSTART(); memcpy(D,S,L); PEND(); \
|
||||
} while(0)
|
||||
@@ -191,6 +198,7 @@ static void *getStructureAddress(JNIEnv *, jobject);
|
||||
static ffi_type* getStructureType(JNIEnv *, jobject);
|
||||
static void update_last_error(JNIEnv*, int);
|
||||
|
||||
/** Invokes System.err.println (for debugging only). */
|
||||
static void
|
||||
println(JNIEnv* env, const char* msg) {
|
||||
jclass cls = (*env)->FindClass(env, "java/lang/System");
|
||||
@@ -229,10 +237,11 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
nargs = (*env)->GetArrayLength(env, arr);
|
||||
|
||||
if (nargs > MAX_NARGS) {
|
||||
sprintf(msg, "Too many arguments (max %ld)", MAX_NARGS);
|
||||
snprintf(msg, sizeof(msg), "Too many arguments (max %ld)", MAX_NARGS);
|
||||
throwByName(env, EUnsupportedOperation, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
c_args = (jvalue*)alloca(nargs * sizeof(jvalue));
|
||||
array_elements = (struct _array_elements*)
|
||||
alloca(nargs * sizeof(struct _array_elements));
|
||||
@@ -277,7 +286,7 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
ffi_values[i] = &c_args[i].i;
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "Unsupported wchar_t size (%d)", (int)sizeof(wchar_t));
|
||||
snprintf(msg, sizeof(msg), "Unsupported wchar_t size (%d)", (int)sizeof(wchar_t));
|
||||
throwByName(env, EUnsupportedOperation, msg);
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -312,7 +321,8 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
ffi_types[i] = getStructureType(env, arg);
|
||||
ffi_values[i] = c_args[i].l;
|
||||
if (!ffi_types[i]) {
|
||||
sprintf(msg, "Structure type info not initialized at argument %d", i);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Structure type info not initialized at argument %d", i);
|
||||
throwByName(env, EIllegalState, msg);
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -322,22 +332,22 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
ffi_types[i] = &ffi_type_pointer;
|
||||
ffi_values[i] = &c_args[i].l;
|
||||
if (c_args[i].l == NULL) {
|
||||
c_args[i].l =
|
||||
getBufferArray(env, arg, &array_elements[array_count].array,
|
||||
&array_elements[array_count].type,
|
||||
&array_elements[array_count].elems);
|
||||
if (c_args[i].l == NULL) {
|
||||
throwByName(env, EIllegalArgument,
|
||||
"Buffer arguments must be direct or have a primitive backing array");
|
||||
goto cleanup;
|
||||
}
|
||||
++array_count;
|
||||
c_args[i].l =
|
||||
getBufferArray(env, arg, &array_elements[array_count].array,
|
||||
&array_elements[array_count].type,
|
||||
&array_elements[array_count].elems);
|
||||
if (c_args[i].l == NULL) {
|
||||
throwByName(env, EIllegalArgument,
|
||||
"Buffer arguments must be direct or have a primitive backing array");
|
||||
goto cleanup;
|
||||
}
|
||||
++array_count;
|
||||
}
|
||||
}
|
||||
else if ((array_pt = getArrayComponentType(env, arg)) != 0
|
||||
&& array_pt != 'L') {
|
||||
void *ptr = NULL;
|
||||
|
||||
|
||||
switch(array_pt) {
|
||||
case 'Z': ptr = (*env)->GetBooleanArrayElements(env, arg, NULL); break;
|
||||
case 'B': ptr = (*env)->GetByteArrayElements(env, arg, NULL); break;
|
||||
@@ -361,9 +371,10 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
array_elements[array_count++].elems = ptr;
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "Unsupported type at parameter %d", i);
|
||||
throwByName(env,EIllegalArgument, msg);
|
||||
goto cleanup;
|
||||
// Anything else, pass directly as a pointer
|
||||
c_args[i].l = (void*)arg;
|
||||
ffi_types[i] = &ffi_type_pointer;
|
||||
ffi_values[i] = &c_args[i].l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,24 +382,33 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
case CALLCONV_C:
|
||||
abi = FFI_DEFAULT_ABI;
|
||||
break;
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
case CALLCONV_STDCALL:
|
||||
#ifdef _WIN64
|
||||
// Ignore requests for stdcall on win64
|
||||
abi = FFI_DEFAULT_ABI;
|
||||
#else
|
||||
abi = FFI_STDCALL;
|
||||
#endif
|
||||
break;
|
||||
#endif // _WIN32
|
||||
default:
|
||||
sprintf(msg, "Unrecognized calling convention: %d", (int)callconv);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Unrecognized calling convention: %d", (int)callconv);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = ffi_prep_cif(&cif, abi, nargs, ffi_return_type, ffi_types);
|
||||
switch(status) {
|
||||
case FFI_BAD_ABI:
|
||||
sprintf(msg, "Invalid calling convention: %d", (int)callconv);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Invalid calling convention: %d", (int)callconv);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
case FFI_BAD_TYPEDEF:
|
||||
sprintf(msg, "Invalid structure definition (native typedef error)");
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Invalid structure definition (native typedef error)");
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
case FFI_OK: {
|
||||
@@ -401,7 +421,8 @@ dispatch(JNIEnv *env, jobject self, jint callconv, jobjectArray arr,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sprintf(msg, "Native call setup failure: error code %d", status);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Native call setup failure: error code %d", status);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
break;
|
||||
}
|
||||
@@ -494,6 +515,21 @@ Java_com_sun_jna_Function_invokePointer(JNIEnv *env, jobject self,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: Function
|
||||
* Method: invokeObject
|
||||
* Signature: (I[Ljava/lang/Object;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_sun_jna_Function_invokeObject(JNIEnv *env, jobject self,
|
||||
jint callconv, jobjectArray arr)
|
||||
{
|
||||
jvalue result;
|
||||
dispatch(env, self, callconv, arr, &ffi_type_pointer, &result);
|
||||
return result.l;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: Function
|
||||
* Method: invokeStructure
|
||||
@@ -505,12 +541,12 @@ Java_com_sun_jna_Function_invokeStructure(JNIEnv *env, jobject self,
|
||||
jobject result)
|
||||
{
|
||||
void* memory = getStructureAddress(env, result);
|
||||
ffi_type* type = getStructureType(env, result);
|
||||
if (!type) {
|
||||
ffi_type* rtype = getStructureType(env, result);
|
||||
if (!rtype) {
|
||||
throwByName(env, EIllegalState, "Return structure type info not initialized");
|
||||
}
|
||||
else {
|
||||
dispatch(env, self, callconv, arr, type, memory);
|
||||
dispatch(env, self, callconv, arr, rtype, memory);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -622,14 +658,20 @@ Java_com_sun_jna_NativeLibrary_open(JNIEnv *env, jclass cls, jstring lib){
|
||||
void *handle = NULL;
|
||||
LIBNAMETYPE libname = NULL;
|
||||
|
||||
if ((libname = LIBNAME2CSTR(env, lib)) != NULL) {
|
||||
handle = (void *)LOAD_LIBRARY(libname);
|
||||
if (!handle) {
|
||||
char buf[1024];
|
||||
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(buf, sizeof(buf)));
|
||||
/* dlopen on Unix allows NULL to mean "current process" */
|
||||
if (lib != NULL) {
|
||||
if ((libname = LIBNAME2CSTR(env, lib)) == NULL) {
|
||||
return (jlong)A2L(NULL);
|
||||
}
|
||||
free(libname);
|
||||
}
|
||||
|
||||
handle = (void *)LOAD_LIBRARY(libname);
|
||||
if (!handle) {
|
||||
char buf[1024];
|
||||
throwByName(env, EUnsatisfiedLink, LOAD_ERROR(buf, sizeof(buf)));
|
||||
}
|
||||
if (libname != NULL)
|
||||
free(libname);
|
||||
return (jlong)A2L(handle);
|
||||
}
|
||||
|
||||
@@ -997,7 +1039,7 @@ JNIEXPORT void JNICALL Java_com_sun_jna_Pointer__1read__J_3SII
|
||||
JNIEXPORT jbyte JNICALL Java_com_sun_jna_Pointer__1getByte
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jbyte res;
|
||||
jbyte res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1010,7 +1052,7 @@ JNIEXPORT jbyte JNICALL Java_com_sun_jna_Pointer__1getByte
|
||||
JNIEXPORT jchar JNICALL Java_com_sun_jna_Pointer__1getChar
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
wchar_t res;
|
||||
wchar_t res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return (jchar)res;
|
||||
}
|
||||
@@ -1023,7 +1065,7 @@ JNIEXPORT jchar JNICALL Java_com_sun_jna_Pointer__1getChar
|
||||
JNIEXPORT jobject JNICALL Java_com_sun_jna_Pointer__1getPointer
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
void *ptr;
|
||||
void *ptr = NULL;
|
||||
MEMCPY(&ptr, L2A(addr), sizeof(ptr));
|
||||
return newJavaPointer(env, ptr);
|
||||
}
|
||||
@@ -1047,7 +1089,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_jna_Pointer__1getDirectByteBuffer
|
||||
JNIEXPORT jdouble JNICALL Java_com_sun_jna_Pointer__1getDouble
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jdouble res;
|
||||
jdouble res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1060,7 +1102,7 @@ JNIEXPORT jdouble JNICALL Java_com_sun_jna_Pointer__1getDouble
|
||||
JNIEXPORT jfloat JNICALL Java_com_sun_jna_Pointer__1getFloat
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jfloat res;
|
||||
jfloat res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1073,7 +1115,7 @@ JNIEXPORT jfloat JNICALL Java_com_sun_jna_Pointer__1getFloat
|
||||
JNIEXPORT jint JNICALL Java_com_sun_jna_Pointer__1getInt
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jint res;
|
||||
jint res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1086,7 +1128,7 @@ JNIEXPORT jint JNICALL Java_com_sun_jna_Pointer__1getInt
|
||||
JNIEXPORT jlong JNICALL Java_com_sun_jna_Pointer__1getLong
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jlong res;
|
||||
jlong res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1099,7 +1141,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_jna_Pointer__1getLong
|
||||
JNIEXPORT jshort JNICALL Java_com_sun_jna_Pointer__1getShort
|
||||
(JNIEnv *env, jclass cls, jlong addr)
|
||||
{
|
||||
jshort res;
|
||||
jshort res = 0;
|
||||
MEMCPY(&res, L2A(addr), sizeof(res));
|
||||
return res;
|
||||
}
|
||||
@@ -1379,7 +1421,7 @@ newJavaString(JNIEnv *env, const char *ptr, jboolean wide)
|
||||
|
||||
if (wide) {
|
||||
// TODO: proper conversion from native wchar_t to jchar
|
||||
int len = wcslen((const wchar_t*)ptr);
|
||||
int len = (int)wcslen((const wchar_t*)ptr);
|
||||
if (sizeof(jchar) != sizeof(wchar_t)) {
|
||||
jchar* buf = (jchar*)alloca(len * sizeof(jchar));
|
||||
int i;
|
||||
@@ -1394,7 +1436,7 @@ newJavaString(JNIEnv *env, const char *ptr, jboolean wide)
|
||||
}
|
||||
else {
|
||||
jbyteArray bytes = 0;
|
||||
int len = strlen(ptr);
|
||||
int len = (int)strlen(ptr);
|
||||
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes != 0) {
|
||||
@@ -1534,39 +1576,32 @@ do { jboolean cpy; \
|
||||
*elemp = ptr;
|
||||
ptr = (char *)ptr + offset;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: Native
|
||||
* Method: pointerSize
|
||||
* Signature: ()I
|
||||
* Method: sizeof
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_sun_jna_Native_pointerSize(JNIEnv *env, jclass cls)
|
||||
Java_com_sun_jna_Native_sizeof(JNIEnv *env, jclass cls, jint type)
|
||||
{
|
||||
return sizeof(void *);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: Native
|
||||
* Method: longSize
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_sun_jna_Native_longSize(JNIEnv *env, jclass cls) {
|
||||
return sizeof(long);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: Native
|
||||
* Method: wideCharSize
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_sun_jna_Native_wideCharSize(JNIEnv *env, jclass cls) {
|
||||
return sizeof(wchar_t);
|
||||
switch(type) {
|
||||
case com_sun_jna_Native_TYPE_VOIDP: return sizeof(void*);
|
||||
case com_sun_jna_Native_TYPE_LONG: return sizeof(long);
|
||||
case com_sun_jna_Native_TYPE_WCHAR_T: return sizeof(wchar_t);
|
||||
case com_sun_jna_Native_TYPE_SIZE_T: return sizeof(size_t);
|
||||
default:
|
||||
{
|
||||
char msg[1024];
|
||||
snprintf(msg, sizeof(msg), "Invalid sizeof type %d", (int)type);
|
||||
throwByName(env, EIllegalArgument, msg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize com.sun.jna classes separately from the library load to
|
||||
@@ -1627,7 +1662,7 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
|
||||
}
|
||||
|
||||
// Initialize type fields within Structure.FFIType
|
||||
{
|
||||
else {
|
||||
#define CFFITYPE "com/sun/jna/Structure$FFIType$FFITypes"
|
||||
jclass cls = (*env)->FindClass(env, CFFITYPE);
|
||||
jfieldID fid;
|
||||
@@ -1652,7 +1687,7 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
|
||||
return;
|
||||
}
|
||||
for (i=0;i < sizeof(fields)/sizeof(fields[0]);i++) {
|
||||
sprintf(field, "ffi_type_%s", fields[i]);
|
||||
snprintf(field, sizeof(field), "ffi_type_%s", fields[i]);
|
||||
fid = (*env)->GetStaticFieldID(env, cls, field, "Lcom/sun/jna/Pointer;");
|
||||
if (!fid) {
|
||||
throwByName(env, EUnsatisfiedLink, field);
|
||||
@@ -1667,13 +1702,13 @@ Java_com_sun_jna_Native_initIDs(JNIEnv *env, jclass cls) {
|
||||
#define JAWT_HEADLESS_HACK
|
||||
#ifdef _WIN32
|
||||
#define JAWT_NAME "jawt.dll"
|
||||
#define METHOD_NAME (sizeof(void*)==4?"_JAWT_GetAWT@8":"_JAWT_GetAWT@16")
|
||||
#define METHOD_NAME (sizeof(void*)==4?"_JAWT_GetAWT@8":"JAWT_GetAWT")
|
||||
#else
|
||||
#define JAWT_NAME "libjawt.so"
|
||||
#define METHOD_NAME "JAWT_GetAWT"
|
||||
#endif
|
||||
static void* jawt_handle = NULL;
|
||||
static jboolean JNICALL (*pJAWT_GetAWT)(JNIEnv*,JAWT*);
|
||||
static jboolean (JNICALL *pJAWT_GetAWT)(JNIEnv*,JAWT*);
|
||||
#define JAWT_GetAWT (*pJAWT_GetAWT)
|
||||
#endif
|
||||
|
||||
@@ -1714,16 +1749,20 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
|
||||
if (java_home != NULL) {
|
||||
if ((prop = newWideCString(env, java_home)) != NULL) {
|
||||
const wchar_t* suffix = L"/bin/jawt.dll";
|
||||
path = (wchar_t*)alloca((wcslen(prop) + wcslen(suffix) + 1)
|
||||
* sizeof(wchar_t));
|
||||
size_t len = wcslen(prop) + wcslen(suffix) + 1;
|
||||
path = (wchar_t*)alloca(len * sizeof(wchar_t));
|
||||
#ifdef _MSC_VER
|
||||
swprintf(path, len, L"%s%s", prop, suffix);
|
||||
#else
|
||||
swprintf(path, L"%s%s", prop, suffix);
|
||||
#endif
|
||||
free(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef LOAD_LIBRARY
|
||||
#define LOAD_LIBRARY(X) LoadLibraryW(path)
|
||||
#undef JAWT_NAME
|
||||
#define JAWT_NAME path
|
||||
#endif
|
||||
if ((jawt_handle = LOAD_LIBRARY(JAWT_NAME)) == NULL) {
|
||||
char msg[1024];
|
||||
@@ -1732,7 +1771,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
|
||||
}
|
||||
if ((pJAWT_GetAWT = (void*)FIND_ENTRY(jawt_handle, METHOD_NAME)) == NULL) {
|
||||
char msg[1024], buf[1024];
|
||||
sprintf(msg, "Error looking up %s: %s",
|
||||
snprintf(msg, sizeof(msg), "Error looking up %s: %s",
|
||||
METHOD_NAME, LOAD_ERROR(buf, sizeof(buf)));
|
||||
throwByName(env, EUnsatisfiedLink, msg);
|
||||
return -1;
|
||||
@@ -1768,7 +1807,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass classp, jobject w)
|
||||
// FIXME this kills the VM if the window is not realized;
|
||||
// if not, wdsi might be a bogus, non-null value
|
||||
// TODO: fix JVM (right) or ensure window is realized (done in Java)
|
||||
handle = (jint)wdsi->hwnd;
|
||||
handle = A2L(wdsi->hwnd);
|
||||
if (!handle) {
|
||||
throwByName(env, EIllegalState, "Can't get HWND");
|
||||
}
|
||||
@@ -1828,14 +1867,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;
|
||||
@@ -2058,9 +2102,8 @@ get_ffi_type(JNIEnv* env, jclass cls, char jtype) {
|
||||
return getStructureType(env, s);
|
||||
}
|
||||
case '*':
|
||||
return &ffi_type_pointer;
|
||||
default:
|
||||
return NULL;
|
||||
return &ffi_type_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2082,7 +2125,136 @@ get_ffi_rtype(JNIEnv* env, jclass cls, char jtype) {
|
||||
return get_ffi_type(env, cls, jtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct _method_data {
|
||||
ffi_cif cif;
|
||||
ffi_cif closure_cif;
|
||||
void* fptr;
|
||||
ffi_type** arg_types;
|
||||
} method_data;
|
||||
|
||||
// VM vectors to this callback, which calls native code
|
||||
static void
|
||||
method_handler(ffi_cif* cif, void* resp, void** argp, void *cdata) {
|
||||
JNIEnv* env = (JNIEnv*)*(void **)argp[0];
|
||||
method_data *data = (method_data*)cdata;
|
||||
// ignore first two arguments, which are pointers
|
||||
void** args = argp + 2;
|
||||
unsigned i;
|
||||
|
||||
// TODO: conversions here otherwise done in JNA interface code
|
||||
// TODO: Pointer, structure by value, primitive arrays
|
||||
for (i=0;i < data->cif.nargs;i++) {
|
||||
if (data->cif.arg_types[i] == &ffi_type_pointer) {
|
||||
if (*(void **)args[i]) {
|
||||
*(void **)args[i] = getNativeAddress(env, *(void **)args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffi_call(&data->cif, FFI_FN(data->fptr), resp, args);
|
||||
|
||||
if (data->cif.rtype == &ffi_type_pointer) {
|
||||
*(void **)resp = newJavaPointer(env, *(void **)resp);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_sun_jna_Native_unregister(JNIEnv *env, jclass ncls, jclass cls, jlongArray handles) {
|
||||
jlong* data = (*env)->GetLongArrayElements(env, handles, NULL);
|
||||
int count = (*env)->GetArrayLength(env, handles);
|
||||
while (count-- > 0) {
|
||||
method_data* md = (method_data*)L2A(data[count]);
|
||||
free(md->arg_types);
|
||||
free(md);
|
||||
}
|
||||
(*env)->ReleaseLongArrayElements(env, handles, data, 0);
|
||||
(*env)->UnregisterNatives(env, cls);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass ncls,
|
||||
jclass cls, jstring name,
|
||||
jstring signature,
|
||||
jobject function, jint cc)
|
||||
{
|
||||
int argc = 0;
|
||||
char* cname = newCStringUTF8(env, name);
|
||||
char* sig = newCStringUTF8(env, signature);
|
||||
void *code;
|
||||
void *closure;
|
||||
method_data* data = malloc(sizeof(method_data));
|
||||
ffi_cif* closure_cif = &data->closure_cif;
|
||||
int status;
|
||||
int i;
|
||||
int abi = FFI_DEFAULT_ABI;
|
||||
char* tmp;
|
||||
ffi_type* rtype;
|
||||
ffi_type** arg_types = alloca(sizeof(ffi_type*)*MAX_NARGS);
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
if (cc == CALLCONV_STDCALL) abi = FFI_STDCALL;
|
||||
#endif
|
||||
|
||||
// Parse the signature for types
|
||||
for (tmp=sig;*tmp;tmp++) {
|
||||
if (*tmp == '(' || *tmp == '[') continue;
|
||||
else if (*tmp == ')') {
|
||||
rtype = get_ffi_rtype(env, NULL, *(tmp+1));
|
||||
break;
|
||||
}
|
||||
else if (*tmp == 'L') {
|
||||
arg_types[argc++] = &ffi_type_pointer;
|
||||
while (*tmp != ';') ++tmp;
|
||||
}
|
||||
else {
|
||||
arg_types[argc++] = get_ffi_type(env, NULL, *tmp);
|
||||
}
|
||||
}
|
||||
|
||||
data->arg_types = malloc(sizeof(ffi_type*)*(argc+2));
|
||||
data->arg_types[0] = &ffi_type_pointer;
|
||||
data->arg_types[1] = &ffi_type_pointer;
|
||||
for (i=0;i < argc;i++) {
|
||||
data->arg_types[i+2] = arg_types[i];
|
||||
}
|
||||
data->fptr = getNativeAddress(env, function);
|
||||
|
||||
status = ffi_prep_cif(closure_cif, abi, argc+2, rtype, data->arg_types);
|
||||
if (status != FFI_OK) {
|
||||
throwByName(env, EError, "Native method mapping failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = ffi_prep_cif(&data->cif, abi, argc, rtype, &data->arg_types[2]);
|
||||
if (status != FFI_OK) {
|
||||
throwByName(env, EError, "Native method setup failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
status = ffi_prep_closure_loc(closure, closure_cif, method_handler, data, code);
|
||||
if (status != FFI_OK) {
|
||||
throwByName(env, EError, "Native method linkage failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
{
|
||||
JNINativeMethod m = { cname, sig, code };
|
||||
(*env)->RegisterNatives(env, cls, &m, 1);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (status != FFI_OK) {
|
||||
free(data->arg_types);
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
free(cname);
|
||||
free(sig);
|
||||
|
||||
return A2L(data);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ extern "C" {
|
||||
/* These are the calling conventions an invocation can handle. */
|
||||
typedef enum _callconv {
|
||||
CALLCONV_C = com_sun_jna_Function_C_CONVENTION,
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
CALLCONV_STDCALL = com_sun_jna_Function_ALT_CONVENTION,
|
||||
#endif
|
||||
} callconv_t;
|
||||
@@ -47,13 +47,19 @@ typedef struct _callback {
|
||||
typedef long word_t;
|
||||
|
||||
#if defined(SOLARIS2) || defined(__GNUC__)
|
||||
#if defined(_WIN64)
|
||||
#define L2A(X) ((void *)(long long)(X))
|
||||
#define A2L(X) ((jlong)(long long)(X))
|
||||
#else
|
||||
#define L2A(X) ((void *)(unsigned long)(X))
|
||||
#define A2L(X) ((jlong)(unsigned long)(X))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define L2A(X) ((void *)(X))
|
||||
#define A2L(X) ((jlong)(X))
|
||||
#define snprintf sprintf_s
|
||||
#endif
|
||||
|
||||
/* Convenience macros */
|
||||
@@ -96,6 +102,17 @@ extern callback* create_callback(JNIEnv*, jobject, jobject,
|
||||
extern void free_callback(JNIEnv*, callback*);
|
||||
extern void extract_value(JNIEnv*, jobject, void*, size_t size);
|
||||
extern jobject new_object(JNIEnv*, char, void*);
|
||||
extern jboolean is_protected();
|
||||
|
||||
/* Native memory fault protection */
|
||||
#ifdef HAVE_PROTECTION
|
||||
#define PROTECT is_protected()
|
||||
#endif
|
||||
#include "protect.h"
|
||||
#define ON_ERROR() throwByName(env, EError, "Invalid memory access")
|
||||
#define PSTART() PROTECTED_START()
|
||||
#define PEND() PROTECTED_END(ON_ERROR())
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Arquivo executável
+56
@@ -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"
|
||||
@@ -1,12 +1,104 @@
|
||||
2007-11-26 Timothy Wall <twall@users.sf.net>
|
||||
2008-12-18 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
PR libffi/26048
|
||||
* configure.ac (HAVE_AS_X86_PCREL): New test.
|
||||
* configure: Regenerate.
|
||||
* fficonfig.h.in: Regenerate.
|
||||
* src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate
|
||||
RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET,
|
||||
RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler.
|
||||
(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
|
||||
* src/x86/unix64.S (.Lstore_table): Move to .text section.
|
||||
(.Lload_table): Likewise.
|
||||
(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
|
||||
|
||||
2008-01-24 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
||||
2008-01-06 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko.
|
||||
|
||||
2008-01-05 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
PR testsuite/32843
|
||||
* src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
|
||||
signed/unsigned int8/16 for X86_DARWIN.
|
||||
Updated copyright info.
|
||||
Handle one and two byte structs with special cif->flags.
|
||||
* src/x86/ffitarget.h: Add special types for one and two byte structs.
|
||||
Updated copyright info.
|
||||
* src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
|
||||
sysv.S
|
||||
Remove code to pop args from the stack after call.
|
||||
Special-case signed/unsigned for int8/16, one and two byte structs.
|
||||
(ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
|
||||
FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
|
||||
FFI_TYPE_SINT32.
|
||||
Updated copyright info.
|
||||
|
||||
2007-12-08 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with
|
||||
SUBU, add with ADDU and use smaller code sequences.
|
||||
|
||||
2007-12-07 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return
|
||||
type.
|
||||
|
||||
2007-12-06 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already
|
||||
defined.
|
||||
(ffi_java_raw): New typedef.
|
||||
(ffi_java_raw_call, ffi_java_ptrarray_to_raw,
|
||||
ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to
|
||||
ffi_java_raw.
|
||||
(ffi_java_raw_closure) : Same.
|
||||
(ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change
|
||||
parameter types.
|
||||
* src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with
|
||||
FFI_SIZEOF_JAVA_RAW.
|
||||
(ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw.
|
||||
Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use
|
||||
sizeof(ffi_java_raw) for alignment calculations.
|
||||
(ffi_java_ptrarray_to_raw): Same.
|
||||
(ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER
|
||||
if FFI_SIZEOF_JAVA_RAW == 4.
|
||||
(ffi_java_raw_to_rvalue): Same.
|
||||
(ffi_java_raw_call): Change type of raw to ffi_java_raw.
|
||||
(ffi_java_translate_args): Same.
|
||||
(ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change
|
||||
parameter types.
|
||||
* src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI.
|
||||
|
||||
2007-12-06 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on
|
||||
pointer values.
|
||||
|
||||
2007-12-01 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
PR libffi/31937
|
||||
* src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
|
||||
Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
|
||||
* src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
|
||||
set the NUM_FPR_ARG_REGISTERS according to.
|
||||
Add support for potential soft-float support under hard-float
|
||||
architecture.
|
||||
(ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
|
||||
FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
|
||||
to the FFI_LINUX_SOFT_FLOAT ABI.
|
||||
(ffi_prep_cif_machdep): Likewise.
|
||||
(ffi_closure_helper_SYSV): Likewise.
|
||||
* src/powerpc/ppc_closure.S: Make sure not to store float/double
|
||||
on archs where __NO_FPRS__ is true.
|
||||
Add FFI_TYPE_UINT128 support.
|
||||
* src/powerpc/sysv.S: Add support for soft-float long-double-128.
|
||||
Adjust copyright notice.
|
||||
|
||||
* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
|
||||
closures.
|
||||
* src/x86/ffitarget.h: Increase size of trampoline for stdcall
|
||||
closures.
|
||||
* src/x86/win32.S: Add assembly for stdcall closure.
|
||||
* src/x86/ffi.c: Initialize stdcall closure trampoline.
|
||||
|
||||
2007-11-25 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* src/closures.c: Move defintion of MAYBE_UNUSED from here to ...
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
2009-05-12 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* Makefile.am,
|
||||
configure.ac,
|
||||
include/ffi.h.in,
|
||||
include/ffi_common.h,
|
||||
src/closures.c,
|
||||
src/dlmalloc.c,
|
||||
src/x86/ffi.c,
|
||||
src/x86/ffitarget.h,
|
||||
src/x86/win64.S (new),
|
||||
README: Added win64 support (mingw or MSVC)
|
||||
* Makefile.in,
|
||||
include/Makefile.in,
|
||||
man/Makefile.in,
|
||||
testsuite/Makefile.in,
|
||||
configure,
|
||||
aclocal.m4: Regenerated
|
||||
* ltcf-c.sh: properly escape cygwin/w32 path
|
||||
* man/ffi_call.3: Clarify size requirements for return value.
|
||||
* src/x86/ffi64.c: Fix filename in comment.
|
||||
* src/x86/win32.S: Remove global reference which causes undefined
|
||||
symbol warning.
|
||||
* testsuite/libffi.call/closure_fn0.c,
|
||||
testsuite/libffi.call/closure_fn1.c,
|
||||
testsuite/libffi.call/closure_fn2.c,
|
||||
testsuite/libffi.call/closure_fn3.c,
|
||||
testsuite/libffi.call/closure_fn4.c,
|
||||
testsuite/libffi.call/closure_fn5.c,
|
||||
testsuite/libffi.call/closure_fn6.c,
|
||||
testsuite/libffi.call/closure_stdcall.c,
|
||||
testsuite/libffi.call/cls_12byte.c,
|
||||
testsuite/libffi.call/cls_16byte.c,
|
||||
testsuite/libffi.call/cls_18byte.c,
|
||||
testsuite/libffi.call/cls_19byte.c,
|
||||
testsuite/libffi.call/cls_1_1byte.c,
|
||||
testsuite/libffi.call/cls_20byte.c,
|
||||
testsuite/libffi.call/cls_20byte1.c,
|
||||
testsuite/libffi.call/cls_24byte.c,
|
||||
testsuite/libffi.call/cls_2byte.c,
|
||||
testsuite/libffi.call/cls_3_1byte.c,
|
||||
testsuite/libffi.call/cls_3byte1.c,
|
||||
testsuite/libffi.call/cls_3byte2.c,
|
||||
testsuite/libffi.call/cls_4_1byte.c,
|
||||
testsuite/libffi.call/cls_4byte.c,
|
||||
testsuite/libffi.call/cls_5_1_byte.c,
|
||||
testsuite/libffi.call/cls_5byte.c,
|
||||
testsuite/libffi.call/cls_64byte.c,
|
||||
testsuite/libffi.call/cls_6_1_byte.c,
|
||||
testsuite/libffi.call/cls_6byte.c,
|
||||
testsuite/libffi.call/cls_7_1_byte.c,
|
||||
testsuite/libffi.call/cls_7byte.c,
|
||||
testsuite/libffi.call/cls_8byte.c,
|
||||
testsuite/libffi.call/cls_9byte1.c,
|
||||
testsuite/libffi.call/cls_9byte2.c,
|
||||
testsuite/libffi.call/cls_align_double.c,
|
||||
testsuite/libffi.call/cls_align_float.c,
|
||||
testsuite/libffi.call/cls_align_longdouble.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split2.c,
|
||||
testsuite/libffi.call/cls_align_pointer.c,
|
||||
testsuite/libffi.call/cls_align_sint16.c,
|
||||
testsuite/libffi.call/cls_align_sint32.c,
|
||||
testsuite/libffi.call/cls_align_sint64.c,
|
||||
testsuite/libffi.call/cls_align_uint16.c,
|
||||
testsuite/libffi.call/cls_align_uint32.c,
|
||||
testsuite/libffi.call/cls_align_uint64.c,
|
||||
testsuite/libffi.call/cls_dbls_struct.c,
|
||||
testsuite/libffi.call/cls_double.c,
|
||||
testsuite/libffi.call/cls_double_va.c,
|
||||
testsuite/libffi.call/cls_float.c,
|
||||
testsuite/libffi.call/cls_longdouble.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/cls_multi_schar.c,
|
||||
testsuite/libffi.call/cls_multi_sshort.c,
|
||||
testsuite/libffi.call/cls_multi_sshortchar.c,
|
||||
testsuite/libffi.call/cls_multi_uchar.c,
|
||||
testsuite/libffi.call/cls_multi_ushort.c,
|
||||
testsuite/libffi.call/cls_multi_ushortchar.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c,
|
||||
testsuite/libffi.call/cls_schar.c,
|
||||
testsuite/libffi.call/cls_sint.c,
|
||||
testsuite/libffi.call/cls_sshort.c,
|
||||
testsuite/libffi.call/cls_uchar.c,
|
||||
testsuite/libffi.call/cls_uint.c,
|
||||
testsuite/libffi.call/cls_ulonglong.c,
|
||||
testsuite/libffi.call/cls_ushort.c,
|
||||
testsuite/libffi.call/err_bad_abi.c,
|
||||
testsuite/libffi.call/err_bad_typedef.c,
|
||||
testsuite/libffi.call/float2.c,
|
||||
testsuite/libffi.call/huge_struct.c,
|
||||
testsuite/libffi.call/nested_struct.c,
|
||||
testsuite/libffi.call/nested_struct1.c,
|
||||
testsuite/libffi.call/nested_struct10.c,
|
||||
testsuite/libffi.call/nested_struct2.c,
|
||||
testsuite/libffi.call/nested_struct3.c,
|
||||
testsuite/libffi.call/nested_struct4.c,
|
||||
testsuite/libffi.call/nested_struct5.c,
|
||||
testsuite/libffi.call/nested_struct6.c,
|
||||
testsuite/libffi.call/nested_struct7.c,
|
||||
testsuite/libffi.call/nested_struct8.c,
|
||||
testsuite/libffi.call/nested_struct9.c,
|
||||
testsuite/libffi.call/problem1.c,
|
||||
testsuite/libffi.call/return_ldl.c,
|
||||
testsuite/libffi.call/return_ll1.c,
|
||||
testsuite/libffi.call/stret_large.c,
|
||||
testsuite/libffi.call/stret_large2.c,
|
||||
testsuite/libffi.call/stret_medium.c,
|
||||
testsuite/libffi.call/stret_medium2.c,
|
||||
testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
|
||||
of checking for MMAP. Use intptr_t instead of long casts.
|
||||
|
||||
2008-12-26 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* testsuite/libffi.call/cls_longdouble.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/cls_align_longdouble.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
|
||||
failures on x86_64 cygwin/mingw.
|
||||
|
||||
2008-12-22 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* testsuite/libffi.call/closure_fn0.c,
|
||||
testsuite/libffi.call/closure_fn1.c,
|
||||
testsuite/libffi.call/closure_fn2.c,
|
||||
testsuite/libffi.call/closure_fn3.c,
|
||||
testsuite/libffi.call/closure_fn4.c,
|
||||
testsuite/libffi.call/closure_fn5.c,
|
||||
testsuite/libffi.call/closure_fn6.c,
|
||||
testsuite/libffi.call/closure_loc_fn0.c,
|
||||
testsuite/libffi.call/closure_stdcall.c,
|
||||
testsuite/libffi.call/cls_align_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
|
||||
pointer to integer (intptr_t).
|
||||
* testsuite/libffi.call/cls_longdouble.c: disable for win64.
|
||||
|
||||
2008-12-19 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.8.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-11-11 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.7.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-08-25 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
|
||||
FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
|
||||
Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
|
||||
Adjust copyright notice.
|
||||
* src/powerpc/ffi.c: Add two new flags to indicate if we have one
|
||||
register or two register to use for FFI_SYSV structs.
|
||||
(ffi_prep_cif_machdep): Pass the right register flag introduced above.
|
||||
(ffi_closure_helper_SYSV): Fix the return type for
|
||||
FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
|
||||
Adjust copyright notice.
|
||||
|
||||
2008-07-24 Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/cls_dbls_struct.c,
|
||||
testsuite/libffi.call/cls_double_va.c,
|
||||
testsuite/libffi.call/cls_longdouble.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c,
|
||||
testsuite/libffi.call/err_bad_abi.c: Clean up failures from
|
||||
compiler warnings.
|
||||
|
||||
2008-07-17 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.6.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision. Add documentation.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-07-16 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
|
||||
int.
|
||||
|
||||
2008-07-16 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* src/sh/sysv.S: Add .note.GNU-stack on Linux.
|
||||
* src/sh64/sysv.S: Likewise.
|
||||
|
||||
2008-04-03 Anthony Green <green@redhat.com>
|
||||
|
||||
* libffi.pc.in (Libs): Add -L${libdir}.
|
||||
* configure.ac: Bump version to 3.0.5.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-04-03 Anthony Green <green@redhat.com>
|
||||
Xerces Ranby <xerxes@zafena.se>
|
||||
|
||||
* include/ffi.h.in: Wrap definition of target architecture to
|
||||
protect from double definitions.
|
||||
|
||||
2008-03-22 Moriyoshi Koizumi <moriyoshi@gmail.com>
|
||||
|
||||
* src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in
|
||||
closure_loc_fn0.c.
|
||||
* testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0):
|
||||
New test.
|
||||
|
||||
2008-03-04 Anthony Green <green@redhat.com>
|
||||
Blake Chaffin
|
||||
hos@tamanegi.org
|
||||
|
||||
* testsuite/libffi.call/cls_align_longdouble_split2.c
|
||||
testsuite/libffi.call/cls_align_longdouble_split.c
|
||||
testsuite/libffi.call/cls_dbls_struct.c
|
||||
testsuite/libffi.call/cls_double_va.c
|
||||
testsuite/libffi.call/cls_longdouble.c
|
||||
testsuite/libffi.call/cls_longdouble_va.c
|
||||
testsuite/libffi.call/cls_pointer.c
|
||||
testsuite/libffi.call/cls_pointer_stack.c
|
||||
testsuite/libffi.call/err_bad_abi.c
|
||||
testsuite/libffi.call/err_bad_typedef.c
|
||||
testsuite/libffi.call/huge_struct.c
|
||||
testsuite/libffi.call/stret_large2.c
|
||||
testsuite/libffi.call/stret_large.c
|
||||
testsuite/libffi.call/stret_medium2.c
|
||||
testsuite/libffi.call/stret_medium.c: New tests from Apple.
|
||||
|
||||
2008-02-26 Jakub Jelinek <jakub@redhat.com>
|
||||
Anthony Green <green@redhat.com>
|
||||
|
||||
* src/alpha/osf.S: Add .note.GNU-stack on Linux.
|
||||
* src/s390/sysv.S: Likewise.
|
||||
* src/powerpc/linux64.S: Likewise.
|
||||
* src/powerpc/linux64_closure.S: Likewise.
|
||||
* src/powerpc/ppc_closure.S: Likewise.
|
||||
* src/powerpc/sysv.S: Likewise.
|
||||
* src/x86/unix64.S: Likewise.
|
||||
* src/x86/sysv.S: Likewise.
|
||||
* src/sparc/v8.S: Likewise.
|
||||
* src/sparc/v9.S: Likewise.
|
||||
* src/m68k/sysv.S: Likewise.
|
||||
* src/ia64/unix.S: Likewise.
|
||||
* src/arm/sysv.S: Likewise.
|
||||
|
||||
2008-02-26 Anthony Green <green@redhat.com>
|
||||
Thomas Heller <theller@ctypes.org>
|
||||
|
||||
* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
|
||||
comment.
|
||||
|
||||
2008-02-26 Anthony Green <green@redhat.org>
|
||||
Thomas Heller <theller@ctypes.org>
|
||||
|
||||
* include/ffi.h.in: Change void (*)() to void (*)(void).
|
||||
|
||||
2008-02-26 Anthony Green <green@redhat.org>
|
||||
Thomas Heller <theller@ctypes.org>
|
||||
|
||||
* src/alpha/ffi.c: Change void (*)() to void (*)(void).
|
||||
src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c,
|
||||
src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c,
|
||||
src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S,
|
||||
src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c,
|
||||
src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c,
|
||||
src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,
|
||||
src/x86/ffi64.c: Ditto.
|
||||
|
||||
2008-02-24 Anthony Green <green@redhat.org>
|
||||
|
||||
* configure.ac: Accept openbsd*, not just openbsd.
|
||||
Bump version to 3.0.4.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-02-22 Anthony Green <green@redhat.com>
|
||||
|
||||
* README: Clean up list of tested platforms.
|
||||
|
||||
2008-02-22 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.3.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release. Clean up test docs.
|
||||
|
||||
2008-02-22 Bjoern Koenig <bkoenig@alpha-tierchen.de>
|
||||
Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* configure.ac: Add amd64-*-freebsd* target.
|
||||
* configure: Regenerate.
|
||||
|
||||
2008-02-22 Thomas Heller <theller@ctypes.org>
|
||||
|
||||
* configure.ac: Add x86 OpenBSD support.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2008-02-21 Thomas Heller <theller@ctypes.org>
|
||||
|
||||
* README: Change "make test" to "make check".
|
||||
|
||||
2008-02-21 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.2.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-02-21 Björn König <bkoenig@alpha-tierchen.de>
|
||||
|
||||
* src/x86/freebsd.S: New file.
|
||||
* configure.ac: Add x86 FreeBSD support.
|
||||
* Makefile.am: Ditto.
|
||||
|
||||
2008-02-15 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.1.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* libtool-version: Increment revision.
|
||||
* README: Update for new release.
|
||||
|
||||
2008-02-15 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* src/mips/ffi.c: Remove extra '>' from include directive.
|
||||
(ffi_prep_closure_loc): Use clear_location instead of tramp.
|
||||
|
||||
2008-02-15 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.0.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
|
||||
2008-02-15 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
|
||||
Define (conditionally), and use it to include cachectl.h.
|
||||
(ffi_prep_closure_loc): Fix cache flushing.
|
||||
* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
|
||||
|
||||
2008-02-15 Anthony Green <green@redhat.com>
|
||||
|
||||
* man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3:
|
||||
Update dates and remove all references to ffi_prep_closure.
|
||||
* configure.ac: Bump version to 2.99.9.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
|
||||
2008-02-15 Anthony Green <green@redhat.com>
|
||||
|
||||
* man/ffi_prep_closure.3: Delete.
|
||||
* man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3.
|
||||
(man_MANS): Ditto.
|
||||
* man/Makefile.in: Rebuilt.
|
||||
* configure.ac: Bump version to 2.99.8.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 2.99.7.
|
||||
* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
|
||||
* include/ffi.h.in LICENSE src/debug.c src/closures.c
|
||||
src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h
|
||||
src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c
|
||||
src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S
|
||||
src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c
|
||||
src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c
|
||||
src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S
|
||||
src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h
|
||||
src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c
|
||||
src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S
|
||||
src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h
|
||||
src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h
|
||||
src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S
|
||||
src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h
|
||||
src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S
|
||||
src/arm/ffitarget.h src/prep_cif.c: Update license text.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* README: Update tested platforms.
|
||||
* configure.ac: Bump version to 2.99.6.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 2.99.5.
|
||||
* configure: Rebuilt.
|
||||
* Makefile.am (EXTRA_DIST): Add darwin64.S
|
||||
* Makefile.in: Rebuilt.
|
||||
* testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree.
|
||||
* LICENSE: Update WARRANTY.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* libffi.pc.in (libdir): Fix libdir definition.
|
||||
* configure.ac: Bump version to 2.99.4.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* README: Update.
|
||||
* libffi.info: New file.
|
||||
* doc/stamp-vti: New file.
|
||||
* configure.ac: Bump version to 2.99.3.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* Makefile.am (SUBDIRS): Add man dir.
|
||||
* Makefile.in: Rebuilt.
|
||||
* configure.ac: Create Makefile.
|
||||
* configure: Rebuilt.
|
||||
* man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3
|
||||
man/Makefile.am man/Makefile.in: New files.
|
||||
|
||||
2008-02-14 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt.
|
||||
* mdate-sh, texinfo.tex: New files.
|
||||
* Makefile.am (info_TEXINFOS): New variable.
|
||||
* doc/libffi.texi: New file.
|
||||
* doc/version.texi: Likewise.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET).
|
||||
(lib_LTLIBRARIES): Define.
|
||||
(toolexeclib_LIBRARIES): Undefine.
|
||||
* Makefile.in: Rebuilt.
|
||||
* configure.ac: Reset version to 2.99.1.
|
||||
* configure.in: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@.
|
||||
* configure.ac: Reset version to 2.99.1.
|
||||
* configure.in: Rebuilt.
|
||||
* Makefile.am (EXTRA_DIST): Add ChangeLog.libffi.
|
||||
* Makefile.in: Rebuilt.
|
||||
* LICENSE: Update copyright notice.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* include/Makefile.am (nodist_includes_HEADERS): Define. Don't
|
||||
distribute ffitarget.h or ffi.h from the build include dir.
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2008-02-14 Anthony Green <green@redhat.com>
|
||||
|
||||
* include/Makefile.am (includesdir): Install headers under libdir.
|
||||
(pkgconfigdir): Define. Install libffi.pc.
|
||||
* include/Makefile.in: Rebuilt.
|
||||
* libffi.pc.in: Create.
|
||||
* libtool-version: Increment CURRENT
|
||||
* configure.ac: Add libffi.pc.in
|
||||
* configure: Rebuilt.
|
||||
|
||||
2008-02-03 Anthony Green <green@redhat.com>
|
||||
|
||||
* include/Makefile.am (includesdir): Fix header install with
|
||||
DESTDIR.
|
||||
* include/Makefile.in: Rebuilt.
|
||||
|
||||
2008-02-03 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
|
||||
offset based on code pointer, not data pointer.
|
||||
|
||||
2008-02-01 Anthony Green <green@redhat.com>
|
||||
|
||||
* include/Makefile.am: Fix header installs.
|
||||
* Makefile.am: Ditto.
|
||||
* include/Makefile.in: Rebuilt.
|
||||
* Makefile.in: Ditto.
|
||||
|
||||
2008-02-01 Anthony Green <green@redhat.com>
|
||||
|
||||
* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL,
|
||||
FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last
|
||||
patch.
|
||||
|
||||
2008-01-31 Anthony Green <green@redhat.com>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add missing files.
|
||||
* testsuite/Makefile.am: Ditto.
|
||||
* Makefile.in, testsuite/Makefile.in: Rebuilt.
|
||||
|
||||
2008-01-31 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
|
||||
closures.
|
||||
* src/x86/ffitarget.h: Increase size of trampoline for stdcall
|
||||
closures.
|
||||
* src/x86/win32.S: Add assembly for stdcall closure.
|
||||
* src/x86/ffi.c: Initialize stdcall closure trampoline.
|
||||
|
||||
2008-01-30 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR libffi/34612
|
||||
* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
|
||||
returning struct.
|
||||
|
||||
* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
|
||||
tests.
|
||||
|
||||
2008-01-30 Anthony Green <green@redhat.com>
|
||||
|
||||
* Makefile.am, include/Makefile.am: Move headers to
|
||||
libffi_la_SOURCES for new automake.
|
||||
* Makefile.in, include/Makefile.in: Rebuilt.
|
||||
|
||||
* testsuite/lib/wrapper.exp: Copied from gcc tree to allow for
|
||||
execution outside of gcc tree.
|
||||
* testsuite/lib/target-libpath.exp: Ditto.
|
||||
|
||||
* testsuite/lib/libffi-dg.exp: Many changes to allow for execution
|
||||
outside of gcc tree.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
libffi - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
libffi - Copyright (c) 1996-2008 Red Hat, Inc and others.
|
||||
See source files for details.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -11,10 +12,10 @@ the following conditions:
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
## Process this with automake to create Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
ACLOCAL_AMFLAGS = -I .. -I ../config
|
||||
|
||||
SUBDIRS = include testsuite
|
||||
SUBDIRS = include testsuite man
|
||||
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
@@ -25,11 +24,15 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
|
||||
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/sparc/ffi.c src/x86/darwin64.S \
|
||||
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/win64.S \
|
||||
src/x86/darwin.S src/x86/freebsd.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
|
||||
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \
|
||||
libtool-version ChangeLog.libffi
|
||||
|
||||
info_TEXINFOS = doc/libffi.texi
|
||||
|
||||
## ################################################################
|
||||
|
||||
@@ -76,12 +79,15 @@ AM_MAKEFLAGS = \
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
toolexeclib_LTLIBRARIES = libffi.la
|
||||
lib_LTLIBRARIES = libffi.la
|
||||
noinst_LTLIBRARIES = libffi_convenience.la
|
||||
|
||||
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
||||
src/raw_api.c src/java_raw_api.c src/closures.c
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libffi.pc
|
||||
|
||||
nodist_libffi_la_SOURCES =
|
||||
|
||||
if MIPS
|
||||
@@ -90,9 +96,15 @@ endif
|
||||
if X86
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
|
||||
endif
|
||||
if X86_FREEBSD
|
||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
|
||||
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
|
||||
@@ -166,10 +178,3 @@ AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
install-html:
|
||||
install-pdf:
|
||||
|
||||
# Multilib support. Automake should provide these on its own.
|
||||
all-recursive: all-multi
|
||||
install-recursive: install-multi
|
||||
mostlyclean-recursive: mostlyclean-multi
|
||||
clean-recursive: clean-multi
|
||||
distclean-recursive: distclean-multi
|
||||
maintainer-clean-recursive: maintainer-clean-multi
|
||||
|
||||
+610
-325
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+120
-274
@@ -1,78 +1,72 @@
|
||||
This directory contains the libffi package, which is not part of GCC but
|
||||
shipped with GCC as convenience.
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
libffi-2.00 has not been released yet! This is a development snapshot!
|
||||
|
||||
libffi-1.20 was released on October 5, 1998. Check the libffi web
|
||||
page for updates: <URL:http://sources.redhat.com/libffi/>.
|
||||
libffi-3.0.8 was released on December 19, 2008. Check the libffi web
|
||||
page for updates: <URL:http://sourceware.org/libffi/>.
|
||||
|
||||
|
||||
What is libffi?
|
||||
===============
|
||||
|
||||
Compilers for high level languages generate code that follow certain
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the "calling
|
||||
convention". The "calling convention" is essentially a set of
|
||||
assumptions made by the compiler about where function arguments will
|
||||
be found on entry to a function. A "calling convention" also specifies
|
||||
where the return value for a function is found.
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the "calling convention".
|
||||
The "calling convention" is a set of assumptions made by the compiler
|
||||
about where function arguments will be found on entry to a function.
|
||||
A "calling convention" also specifies where the return value for a
|
||||
function is found.
|
||||
|
||||
Some programs may not know at the time of compilation what arguments
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
told at run-time about the number and types of arguments used to call
|
||||
a given function. Libffi can be used in such programs to provide a
|
||||
a given function. Libffi can be used in such programs to provide a
|
||||
bridge from the interpreter program to compiled code.
|
||||
|
||||
The libffi library provides a portable, high level programming
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
call any function specified by a call interface description at run
|
||||
time.
|
||||
time.
|
||||
|
||||
Ffi stands for Foreign Function Interface. A foreign function
|
||||
FFI stands for Foreign Function Interface. A foreign function
|
||||
interface is the popular name for the interface that allows code
|
||||
written in one language to call code written in another language. The
|
||||
written in one language to call code written in another language. The
|
||||
libffi library really only provides the lowest, machine dependent
|
||||
layer of a fully featured foreign function interface. A layer must
|
||||
exist above libffi that handles type conversions for values passed
|
||||
between the two languages.
|
||||
|
||||
|
||||
Supported Platforms and Prerequisites
|
||||
=====================================
|
||||
Supported Platforms
|
||||
===================
|
||||
|
||||
Libffi has been ported to:
|
||||
|
||||
SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
|
||||
|
||||
Irix 5.3 & 6.2 (System V/o32 & n32)
|
||||
|
||||
Intel x86 - Linux (System V ABI)
|
||||
|
||||
Alpha - Linux and OSF/1
|
||||
|
||||
m68k - Linux (System V ABI)
|
||||
|
||||
PowerPC - Linux (System V ABI, Darwin, AIX)
|
||||
|
||||
ARM - Linux (System V ABI)
|
||||
|
||||
Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
|
||||
that other versions will work. Libffi has also been built and tested
|
||||
with the SGI compiler tools.
|
||||
|
||||
On PowerPC, the tests failed (see the note below).
|
||||
|
||||
You must use GNU make to build libffi. SGI's make will not work.
|
||||
Sun's probably won't either.
|
||||
|
||||
If you port libffi to another platform, please let me know! I assume
|
||||
that some will be easy (x86 NetBSD), and others will be more difficult
|
||||
(HP).
|
||||
Libffi has been ported to many different platforms, although this
|
||||
release was only tested on:
|
||||
|
||||
arm oabi linux
|
||||
arm eabi linux
|
||||
hppa linux
|
||||
mips o32 linux (little endian)
|
||||
powerpc darwin
|
||||
powerpc freebsd
|
||||
powerpc64 linux
|
||||
sparc solaris
|
||||
sparc64 freebsd
|
||||
sparc64 solaris
|
||||
x86 cygwin
|
||||
x86 darwin
|
||||
x86 freebsd
|
||||
x86 linux
|
||||
x86 openbsd
|
||||
x86 solaris
|
||||
x86-64 mingw
|
||||
x86-64 darwin
|
||||
x86-64 linux
|
||||
x86-64 OS X
|
||||
x86-64 freebsd
|
||||
x86-64 solaris
|
||||
|
||||
Please send additional platform test results to
|
||||
libffi-discuss@sourceware.org.
|
||||
|
||||
Installing libffi
|
||||
=================
|
||||
@@ -101,216 +95,17 @@ Purify, as it will slow down the library.
|
||||
Configure has many other options. Use "configure --help" to see them all.
|
||||
|
||||
Once configure has finished, type "make". Note that you must be using
|
||||
GNU make. SGI's make will not work. Sun's probably won't either.
|
||||
You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
|
||||
GNU make. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
|
||||
|
||||
To ensure that libffi is working as advertised, type "make test".
|
||||
To ensure that libffi is working as advertised, type "make check".
|
||||
This will require that you have DejaGNU installed.
|
||||
|
||||
To install the library and header files, type "make install".
|
||||
|
||||
|
||||
Using libffi
|
||||
============
|
||||
|
||||
The Basics
|
||||
----------
|
||||
|
||||
Libffi assumes that you have a pointer to the function you wish to
|
||||
call and that you know the number and types of arguments to pass it,
|
||||
as well as the return type of the function.
|
||||
|
||||
The first thing you must do is create an ffi_cif object that matches
|
||||
the signature of the function you wish to call. The cif in ffi_cif
|
||||
stands for Call InterFace. To prepare a call interface object, use the
|
||||
following function:
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype, ffi_type **atypes);
|
||||
|
||||
CIF is a pointer to the call interface object you wish
|
||||
to initialize.
|
||||
|
||||
ABI is an enum that specifies the calling convention
|
||||
to use for the call. FFI_DEFAULT_ABI defaults
|
||||
to the system's native calling convention. Other
|
||||
ABI's may be used with care. They are system
|
||||
specific.
|
||||
|
||||
NARGS is the number of arguments this function accepts.
|
||||
libffi does not yet support vararg functions.
|
||||
|
||||
RTYPE is a pointer to an ffi_type structure that represents
|
||||
the return type of the function. Ffi_type objects
|
||||
describe the types of values. libffi provides
|
||||
ffi_type objects for many of the native C types:
|
||||
signed int, unsigned int, signed char, unsigned char,
|
||||
etc. There is also a pointer ffi_type object and
|
||||
a void ffi_type. Use &ffi_type_void for functions that
|
||||
don't return values.
|
||||
|
||||
ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
|
||||
If NARGS is 0, this is ignored.
|
||||
|
||||
|
||||
ffi_prep_cif will return a status code that you are responsible
|
||||
for checking. It will be one of the following:
|
||||
|
||||
FFI_OK - All is good.
|
||||
|
||||
FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
|
||||
came across is bad.
|
||||
|
||||
|
||||
Before making the call, the VALUES vector should be initialized
|
||||
with pointers to the appropriate argument values.
|
||||
|
||||
To call the the function using the initialized ffi_cif, use the
|
||||
ffi_call function:
|
||||
|
||||
void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
|
||||
|
||||
CIF is a pointer to the ffi_cif initialized specifically
|
||||
for this function.
|
||||
|
||||
FN is a pointer to the function you want to call.
|
||||
|
||||
RVALUE is a pointer to a chunk of memory that is to hold the
|
||||
result of the function call. Currently, it must be
|
||||
at least one word in size (except for the n32 version
|
||||
under Irix 6.x, which must be a pointer to an 8 byte
|
||||
aligned value (a long long). It must also be at least
|
||||
word aligned (depending on the return type, and the
|
||||
system's alignment requirements). If RTYPE is
|
||||
&ffi_type_void, this is ignored. If RVALUE is NULL,
|
||||
the return value is discarded.
|
||||
|
||||
AVALUES is a vector of void* that point to the memory locations
|
||||
holding the argument values for a call.
|
||||
If NARGS is 0, this is ignored.
|
||||
|
||||
|
||||
If you are expecting a return value from FN it will have been stored
|
||||
at RVALUE.
|
||||
|
||||
|
||||
|
||||
An Example
|
||||
----------
|
||||
|
||||
Here is a trivial example that calls puts() a few times.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
void *values[1];
|
||||
char *s;
|
||||
int rc;
|
||||
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
values[0] = &s;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
{
|
||||
s = "Hello World!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
/* rc now holds the result of the call to puts */
|
||||
|
||||
/* values holds a pointer to the function's arg, so to
|
||||
call puts() again all we need to do is change the
|
||||
value of s */
|
||||
s = "This is cool!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Aggregate Types
|
||||
---------------
|
||||
|
||||
Although libffi has no special support for unions or bit-fields, it is
|
||||
perfectly happy passing structures back and forth. You must first
|
||||
describe the structure to libffi by creating a new ffi_type object
|
||||
for it. Here is the definition of ffi_type:
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
unsigned size;
|
||||
short alignment;
|
||||
short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
All structures must have type set to FFI_TYPE_STRUCT. You may set
|
||||
size and alignment to 0. These will be calculated and reset to the
|
||||
appropriate values by ffi_prep_cif().
|
||||
|
||||
elements is a NULL terminated array of pointers to ffi_type objects
|
||||
that describe the type of the structure elements. These may, in turn,
|
||||
be structure elements.
|
||||
|
||||
The following example initializes a ffi_type object representing the
|
||||
tm struct from Linux's time.h:
|
||||
|
||||
struct tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
/* Those are for future use. */
|
||||
long int __tm_gmtoff__;
|
||||
__const char *__tm_zone__;
|
||||
};
|
||||
|
||||
{
|
||||
ffi_type tm_type;
|
||||
ffi_type *tm_type_elements[12];
|
||||
int i;
|
||||
|
||||
tm_type.size = tm_type.alignment = 0;
|
||||
tm_type.elements = &tm_type_elements;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
tm_type_elements[i] = &ffi_type_sint;
|
||||
|
||||
tm_type_elements[9] = &ffi_type_slong;
|
||||
tm_type_elements[10] = &ffi_type_pointer;
|
||||
tm_type_elements[11] = NULL;
|
||||
|
||||
/* tm_type can now be used to represent tm argument types and
|
||||
return types for ffi_prep_cif() */
|
||||
}
|
||||
|
||||
|
||||
|
||||
Platform Specific Notes
|
||||
=======================
|
||||
|
||||
Intel x86
|
||||
---------
|
||||
|
||||
There are no known problems with the x86 port.
|
||||
|
||||
Sun SPARC - SunOS 4.1.3 & Solaris 2.x
|
||||
-------------------------------------
|
||||
|
||||
You must use GNU Make to build libffi on Sun platforms.
|
||||
|
||||
MIPS - Irix 5.3 & 6.x
|
||||
---------------------
|
||||
|
||||
@@ -339,13 +134,6 @@ If you don't do this you are liable to get spurious bus errors.
|
||||
|
||||
You must use GNU Make to build libffi on SGI platforms.
|
||||
|
||||
ARM - System V ABI
|
||||
------------------
|
||||
|
||||
The ARM port was performed on a NetWinder running ARM Linux ELF
|
||||
(2.0.31) and gcc 2.8.1.
|
||||
|
||||
|
||||
|
||||
PowerPC System V ABI
|
||||
--------------------
|
||||
@@ -375,6 +163,42 @@ arguments' test).
|
||||
History
|
||||
=======
|
||||
|
||||
3.0.7 Nov-11-08
|
||||
Fix for ppc FreeBSD.
|
||||
(thanks to Andreas Tobler)
|
||||
|
||||
3.0.6 Jul-17-08
|
||||
Fix for closures on sh.
|
||||
Mark the sh/sh64 stack as non-executable.
|
||||
(both thanks to Kaz Kojima)
|
||||
|
||||
3.0.5 Apr-3-08
|
||||
Fix libffi.pc file.
|
||||
Fix #define ARM for IcedTea users.
|
||||
Fix x86 closure bug.
|
||||
|
||||
3.0.4 Feb-24-08
|
||||
Fix x86 OpenBSD configury.
|
||||
|
||||
3.0.3 Feb-22-08
|
||||
Enable x86 OpenBSD thanks to Thomas Heller, and
|
||||
x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
|
||||
Clean up test instruction in README.
|
||||
|
||||
3.0.2 Feb-21-08
|
||||
Improved x86 FreeBSD support.
|
||||
Thanks to Björn König.
|
||||
|
||||
3.0.1 Feb-15-08
|
||||
Fix instruction cache flushing bug on MIPS.
|
||||
Thanks to David Daney.
|
||||
|
||||
3.0.0 Feb-15-08
|
||||
Many changes, mostly thanks to the GCC project.
|
||||
Cygnus Solutions is now Red Hat.
|
||||
|
||||
[10 years go by...]
|
||||
|
||||
1.20 Oct-5-98
|
||||
Raffaele Sena produces ARM port.
|
||||
|
||||
@@ -458,34 +282,56 @@ History
|
||||
Authors & Credits
|
||||
=================
|
||||
|
||||
libffi was written by Anthony Green <green@cygnus.com>.
|
||||
libffi was originally written by Anthony Green <green@redhat.com>.
|
||||
|
||||
Portions of libffi were derived from Gianni Mariani's free gencall
|
||||
library for Silicon Graphics machines.
|
||||
The developers of the GNU Compiler Collection project have made
|
||||
innumerable valuable contributions. See the ChangeLog file for
|
||||
details.
|
||||
|
||||
Some of the ideas behind libffi were inspired by Gianni Mariani's free
|
||||
gencall library for Silicon Graphics machines.
|
||||
|
||||
The closure mechanism was designed and implemented by Kresten Krab
|
||||
Thorup.
|
||||
|
||||
The Sparc port was derived from code contributed by the fine folks at
|
||||
Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
|
||||
made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
|
||||
Major processor architecture ports were contributed by the following
|
||||
developers:
|
||||
|
||||
The Alpha port was written by Richard Henderson at Cygnus Solutions.
|
||||
|
||||
Andreas Schwab ported libffi to m68k Linux and provided a number of
|
||||
bug fixes.
|
||||
|
||||
Geoffrey Keating ported libffi to the PowerPC.
|
||||
|
||||
Raffaele Sena ported libffi to the ARM.
|
||||
alpha Richard Henderson
|
||||
arm Raffaele Sena
|
||||
cris Simon Posnjak, Hans-Peter Nilsson
|
||||
frv Anthony Green
|
||||
ia64 Hans Boehm
|
||||
m32r Kazuhiro Inaoka
|
||||
m68k Andreas Schwab
|
||||
mips Anthony Green, Casey Marshall
|
||||
mips64 David Daney
|
||||
pa Randolph Chung, Dave Anglin, Andreas Tobler
|
||||
powerpc Geoffrey Keating, Andreas Tobler,
|
||||
David Edelsohn, John Hornkvist
|
||||
powerpc64 Jakub Jelinek
|
||||
s390 Gerhard Tonn, Ulrich Weigand
|
||||
sh Kaz Kojima
|
||||
sh64 Kaz Kojima
|
||||
sparc Anthony Green, Gordon Irlam
|
||||
x86 Anthony Green, Jon Beniston
|
||||
x86-64 Bo Thorsen
|
||||
|
||||
Jesper Skov and Andrew Haley both did more than their fair share of
|
||||
stepping through the code and tracking down bugs.
|
||||
|
||||
Thanks also to Tom Tromey for bug fixes and configuration help.
|
||||
Thanks also to Tom Tromey for bug fixes, documentation and
|
||||
configuration help.
|
||||
|
||||
Thanks to Jim Blandy, who provided some useful feedback on the libffi
|
||||
interface.
|
||||
|
||||
Andreas Tobler has done a tremendous amount of work on the testsuite.
|
||||
|
||||
Alex Oliva solved the executable page problem for SElinux.
|
||||
|
||||
The list above is almost certainly incomplete and inaccurate. I'm
|
||||
happy to make corrections or additions upon request.
|
||||
|
||||
If you have a problem, or have found a bug, please send a note to
|
||||
green@cygnus.com.
|
||||
green@redhat.com.
|
||||
|
||||
Arquivo executável
+3
@@ -0,0 +1,3 @@
|
||||
To run the testsuite on win64, make your mingw compiler available in the path
|
||||
as "gcc". This could probably be avoided via additional dejagnu configuration,
|
||||
but I haven't figured out how.
|
||||
externo
+6771
-104
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Arquivo executável
+142
@@ -0,0 +1,142 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand `-c -o'.
|
||||
|
||||
scriptversion=2005-05-14.22
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand `-c -o'.
|
||||
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file `INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
eat=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||
# So we strip `-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no `-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# `.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use `[/.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -16,8 +16,8 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
@@ -551,7 +551,6 @@ multi-do:
|
||||
flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
|
||||
if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) \
|
||||
CFLAGS="$(CFLAGS) $${flags}" \
|
||||
CCASFLAGS="$(CCASFLAGS) $${flags}" \
|
||||
FCFLAGS="$(FCFLAGS) $${flags}" \
|
||||
FFLAGS="$(FFLAGS) $${flags}" \
|
||||
ADAFLAGS="$(ADAFLAGS) $${flags}" \
|
||||
@@ -586,8 +585,8 @@ multi-clean:
|
||||
true; \
|
||||
else \
|
||||
lib=`${PWD_COMMAND} | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \
|
||||
for dir in ${Makefile} $(MULTIDIRS); do \
|
||||
if [ -f ../$${dir}/$${lib}/${Makefile} ]; then \
|
||||
for dir in Makefile $(MULTIDIRS); do \
|
||||
if [ -f ../$${dir}/$${lib}/Makefile ]; then \
|
||||
if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \
|
||||
then true; \
|
||||
else exit 1; \
|
||||
@@ -605,7 +604,7 @@ mv Makefile.tem ${Makefile}
|
||||
fi # ${ml_toplevel_p} = yes
|
||||
|
||||
if [ "${ml_verbose}" = --verbose ]; then
|
||||
echo "Adding multilib support to ${Makefile} in ${ml_realsrcdir}"
|
||||
echo "Adding multilib support to Makefile in ${ml_realsrcdir}"
|
||||
if [ "${ml_toplevel_p}" = yes ]; then
|
||||
echo "multidirs=${multidirs}"
|
||||
fi
|
||||
@@ -740,7 +739,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
|
||||
fi
|
||||
(cd ${ml_dir}/${ml_libdir};
|
||||
../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "")
|
||||
if [ -f ${ml_dir}/${ml_libdir}/${Makefile} ]; then
|
||||
if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then
|
||||
if [ x"${MAKE}" = x ]; then
|
||||
(cd ${ml_dir}/${ml_libdir}; make distclean)
|
||||
else
|
||||
@@ -895,7 +894,7 @@ if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
|
||||
|
||||
if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \
|
||||
--with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
|
||||
${ac_configure_args} ${ml_config_env} ${ml_srcdiroption} ; then
|
||||
${ac_configure_args} ${ml_srcdiroption} ; then
|
||||
true
|
||||
else
|
||||
exit 1
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2007-07-22'
|
||||
timestamp='2007-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -330,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
@@ -793,7 +793,7 @@ EOF
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
|
||||
externo
+3
-3
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2007-06-28'
|
||||
timestamp='2007-04-29'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -475,8 +475,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16)
|
||||
basic_machine=cr16-unknown
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
|
||||
externo
+17480
-7677
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -2,11 +2,9 @@ dnl Process this with autoconf to create configure
|
||||
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html])
|
||||
AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AM_ENABLE_MULTILIB(, ..)
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
|
||||
@@ -51,6 +49,10 @@ case "$host" in
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
cris-*-*)
|
||||
TARGET=LIBFFI_CRIS; TARGETDIR=cris
|
||||
;;
|
||||
@@ -69,6 +71,9 @@ case "$host" in
|
||||
TARGET=PA_HPUX; TARGETDIR=pa
|
||||
;;
|
||||
|
||||
i386-*-freebsd* | i386-*-openbsd*)
|
||||
TARGET=X86_FREEBSD; TARGETDIR=x86
|
||||
;;
|
||||
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
|
||||
TARGET=X86_WIN32; TARGETDIR=x86
|
||||
;;
|
||||
@@ -139,6 +144,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
|
||||
@@ -154,7 +160,9 @@ fi
|
||||
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
|
||||
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
|
||||
AM_CONDITIONAL(X86, test x$TARGET = xX86)
|
||||
AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
|
||||
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)
|
||||
@@ -239,6 +247,21 @@ if test x$TARGET = xSPARC; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$TARGET = xX86 || test x$TARGET = xX86_64; then
|
||||
AC_CACHE_CHECK([assembler supports pc related relocs],
|
||||
libffi_cv_as_x86_pcrel, [
|
||||
libffi_cv_as_x86_pcrel=yes
|
||||
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
|
||||
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
|
||||
libffi_cv_as_x86_pcrel=no
|
||||
fi
|
||||
])
|
||||
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
|
||||
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
|
||||
[Define if your assembler supports PC relative relocs.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
|
||||
libffi_cv_ro_eh_frame, [
|
||||
libffi_cv_ro_eh_frame=no
|
||||
@@ -354,6 +377,6 @@ test -d src/$TARGETDIR || mkdir src/$TARGETDIR
|
||||
|
||||
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
|
||||
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile)
|
||||
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2005-05-16.16
|
||||
scriptversion=2006-10-15.18
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
|
||||
# Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -91,7 +92,20 @@ gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
@@ -276,27 +290,44 @@ icc)
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
ia64hp)
|
||||
# The "hp" stanza above does not work with HP's ia64 compilers,
|
||||
# which have integrated preprocessors. The correct option to use
|
||||
# with these is +Maked; it writes dependencies to a file named
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
tmpdepfile=`echo "$object" | sed -e 's/\.o$/.d/'`
|
||||
"$@" +Maked
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
# The object file name is correct already.
|
||||
cat "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${; s/^ //; s/ \\*$//; s/$/:/; p; }' "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
@@ -311,13 +342,13 @@ tru64)
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mecanism is used in libtool 1.4 series to
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in in $dir.libs/$base.o.d and
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
|
||||
@@ -0,0 +1,533 @@
|
||||
This is doc/libffi.info, produced by makeinfo version 4.13 from
|
||||
./doc/libffi.texi.
|
||||
|
||||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version. A copy of the license is
|
||||
included in the section entitled "GNU General Public License".
|
||||
|
||||
|
||||
INFO-DIR-SECTION
|
||||
START-INFO-DIR-ENTRY
|
||||
* libffi: (libffi). Portable foreign-function interface library.
|
||||
END-INFO-DIR-ENTRY
|
||||
|
||||
|
||||
File: libffi.info, Node: Top, Next: Introduction, Up: (dir)
|
||||
|
||||
libffi
|
||||
******
|
||||
|
||||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2, or
|
||||
(at your option) any later version. A copy of the license is
|
||||
included in the section entitled "GNU General Public License".
|
||||
|
||||
|
||||
* Menu:
|
||||
|
||||
* Introduction:: What is libffi?
|
||||
* Using libffi:: How to use libffi.
|
||||
* Missing Features:: Things libffi can't do.
|
||||
* Index:: Index.
|
||||
|
||||
|
||||
File: libffi.info, Node: Introduction, Next: Using libffi, Prev: Top, Up: Top
|
||||
|
||||
1 What is libffi?
|
||||
*****************
|
||||
|
||||
Compilers for high level languages generate code that follow certain
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the "calling convention".
|
||||
The calling convention is a set of assumptions made by the compiler
|
||||
about where function arguments will be found on entry to a function. A
|
||||
calling convention also specifies where the return value for a function
|
||||
is found. The calling convention is also sometimes called the "ABI" or
|
||||
"Application Binary Interface".
|
||||
|
||||
Some programs may not know at the time of compilation what arguments
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
told at run-time about the number and types of arguments used to call a
|
||||
given function. `Libffi' can be used in such programs to provide a
|
||||
bridge from the interpreter program to compiled code.
|
||||
|
||||
The `libffi' library provides a portable, high level programming
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
call any function specified by a call interface description at run time.
|
||||
|
||||
FFI stands for Foreign Function Interface. A foreign function
|
||||
interface is the popular name for the interface that allows code
|
||||
written in one language to call code written in another language. The
|
||||
`libffi' library really only provides the lowest, machine dependent
|
||||
layer of a fully featured foreign function interface. A layer must
|
||||
exist above `libffi' that handles type conversions for values passed
|
||||
between the two languages.
|
||||
|
||||
|
||||
File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top
|
||||
|
||||
2 Using libffi
|
||||
**************
|
||||
|
||||
* Menu:
|
||||
|
||||
* The Basics:: The basic libffi API.
|
||||
* Simple Example:: A simple example.
|
||||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi
|
||||
|
||||
2.1 The Basics
|
||||
==============
|
||||
|
||||
`Libffi' assumes that you have a pointer to the function you wish to
|
||||
call and that you know the number and types of arguments to pass it, as
|
||||
well as the return type of the function.
|
||||
|
||||
The first thing you must do is create an `ffi_cif' object that
|
||||
matches the signature of the function you wish to call. This is a
|
||||
separate step because it is common to make multiple calls using a
|
||||
single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace.
|
||||
To prepare a call interface object, use the function `ffi_prep_cif'.
|
||||
|
||||
-- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI,
|
||||
unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES)
|
||||
This initializes CIF according to the given parameters.
|
||||
|
||||
ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you
|
||||
want. *note Multiple ABIs:: for more information.
|
||||
|
||||
NARGS is the number of arguments that this function accepts.
|
||||
`libffi' does not yet handle varargs functions; see *note Missing
|
||||
Features:: for more information.
|
||||
|
||||
RTYPE is a pointer to an `ffi_type' structure that describes the
|
||||
return type of the function. *Note Types::.
|
||||
|
||||
ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have
|
||||
NARGS elements. If NARGS is 0, this argument is ignored.
|
||||
|
||||
`ffi_prep_cif' returns a `libffi' status code, of type
|
||||
`ffi_status'. This will be either `FFI_OK' if everything worked
|
||||
properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is
|
||||
incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid.
|
||||
|
||||
To call a function using an initialized `ffi_cif', use the
|
||||
`ffi_call' function:
|
||||
|
||||
-- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void
|
||||
**AVALUES)
|
||||
This calls the function FN according to the description given in
|
||||
CIF. CIF must have already been prepared using `ffi_prep_cif'.
|
||||
|
||||
RVALUE is a pointer to a chunk of memory that will hold the result
|
||||
of the function call. This must be large enough to hold the
|
||||
result and must be suitably aligned; it is the caller's
|
||||
responsibility to ensure this. If CIF declares that the function
|
||||
returns `void' (using `ffi_type_void'), then RVALUE is ignored.
|
||||
If RVALUE is `NULL', then the return value is discarded.
|
||||
|
||||
AVALUES is a vector of `void *' pointers that point to the memory
|
||||
locations holding the argument values for a call. If CIF declares
|
||||
that the function has no arguments (i.e., NARGS was 0), then
|
||||
AVALUES is ignored.
|
||||
|
||||
|
||||
File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: Using libffi
|
||||
|
||||
2.2 Simple Example
|
||||
==================
|
||||
|
||||
Here is a trivial example that calls `puts' a few times.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
void *values[1];
|
||||
char *s;
|
||||
int rc;
|
||||
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
values[0] = &s;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
{
|
||||
s = "Hello World!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
/* rc now holds the result of the call to puts */
|
||||
|
||||
/* values holds a pointer to the function's arg, so to
|
||||
call puts() again all we need to do is change the
|
||||
value of s */
|
||||
s = "This is cool!";
|
||||
ffi_call(&cif, puts, &rc, values);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, Up: Using libffi
|
||||
|
||||
2.3 Types
|
||||
=========
|
||||
|
||||
* Menu:
|
||||
|
||||
* Primitive Types:: Built-in types.
|
||||
* Structures:: Structure types.
|
||||
* Type Example:: Structure type example.
|
||||
|
||||
|
||||
File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types
|
||||
|
||||
2.3.1 Primitive Types
|
||||
---------------------
|
||||
|
||||
`Libffi' provides a number of built-in type descriptors that can be
|
||||
used to describe argument and return types:
|
||||
|
||||
`ffi_type_void'
|
||||
The type `void'. This cannot be used for argument types, only for
|
||||
return values.
|
||||
|
||||
`ffi_type_uint8'
|
||||
An unsigned, 8-bit integer type.
|
||||
|
||||
`ffi_type_sint8'
|
||||
A signed, 8-bit integer type.
|
||||
|
||||
`ffi_type_uint16'
|
||||
An unsigned, 16-bit integer type.
|
||||
|
||||
`ffi_type_sint16'
|
||||
A signed, 16-bit integer type.
|
||||
|
||||
`ffi_type_uint32'
|
||||
An unsigned, 32-bit integer type.
|
||||
|
||||
`ffi_type_sint32'
|
||||
A signed, 32-bit integer type.
|
||||
|
||||
`ffi_type_uint64'
|
||||
An unsigned, 64-bit integer type.
|
||||
|
||||
`ffi_type_sint64'
|
||||
A signed, 64-bit integer type.
|
||||
|
||||
`ffi_type_float'
|
||||
The C `float' type.
|
||||
|
||||
`ffi_type_double'
|
||||
The C `double' type.
|
||||
|
||||
`ffi_type_uchar'
|
||||
The C `unsigned char' type.
|
||||
|
||||
`ffi_type_schar'
|
||||
The C `signed char' type. (Note that there is not an exact
|
||||
equivalent to the C `char' type in `libffi'; ordinarily you should
|
||||
either use `ffi_type_schar' or `ffi_type_uchar' depending on
|
||||
whether `char' is signed.)
|
||||
|
||||
`ffi_type_ushort'
|
||||
The C `unsigned short' type.
|
||||
|
||||
`ffi_type_sshort'
|
||||
The C `short' type.
|
||||
|
||||
`ffi_type_uint'
|
||||
The C `unsigned int' type.
|
||||
|
||||
`ffi_type_sint'
|
||||
The C `int' type.
|
||||
|
||||
`ffi_type_ulong'
|
||||
The C `unsigned long' type.
|
||||
|
||||
`ffi_type_slong'
|
||||
The C `long' type.
|
||||
|
||||
`ffi_type_longdouble'
|
||||
On platforms that have a C `long double' type, this is defined.
|
||||
On other platforms, it is not.
|
||||
|
||||
`ffi_type_pointer'
|
||||
A generic `void *' pointer. You should use this for all pointers,
|
||||
regardless of their real type.
|
||||
|
||||
Each of these is of type `ffi_type', so you must take the address
|
||||
when passing to `ffi_prep_cif'.
|
||||
|
||||
|
||||
File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types
|
||||
|
||||
2.3.2 Structures
|
||||
----------------
|
||||
|
||||
Although `libffi' has no special support for unions or bit-fields, it
|
||||
is perfectly happy passing structures back and forth. You must first
|
||||
describe the structure to `libffi' by creating a new `ffi_type' object
|
||||
for it.
|
||||
|
||||
-- ffi_type:
|
||||
The `ffi_type' has the following members:
|
||||
`size_t size'
|
||||
This is set by `libffi'; you should initialize it to zero.
|
||||
|
||||
`unsigned short alignment'
|
||||
This is set by `libffi'; you should initialize it to zero.
|
||||
|
||||
`unsigned short type'
|
||||
For a structure, this should be set to `FFI_TYPE_STRUCT'.
|
||||
|
||||
`ffi_type **elements'
|
||||
This is a `NULL'-terminated array of pointers to `ffi_type'
|
||||
objects. There is one element per field of the struct.
|
||||
|
||||
|
||||
File: libffi.info, Node: Type Example, Prev: Structures, Up: Types
|
||||
|
||||
2.3.3 Type Example
|
||||
------------------
|
||||
|
||||
The following example initializes a `ffi_type' object representing the
|
||||
`tm' struct from Linux's `time.h'.
|
||||
|
||||
Here is how the struct is defined:
|
||||
|
||||
struct tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
/* Those are for future use. */
|
||||
long int __tm_gmtoff__;
|
||||
__const char *__tm_zone__;
|
||||
};
|
||||
|
||||
Here is the corresponding code to describe this struct to `libffi':
|
||||
|
||||
{
|
||||
ffi_type tm_type;
|
||||
ffi_type *tm_type_elements[12];
|
||||
int i;
|
||||
|
||||
tm_type.size = tm_type.alignment = 0;
|
||||
tm_type.elements = &tm_type_elements;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
tm_type_elements[i] = &ffi_type_sint;
|
||||
|
||||
tm_type_elements[9] = &ffi_type_slong;
|
||||
tm_type_elements[10] = &ffi_type_pointer;
|
||||
tm_type_elements[11] = NULL;
|
||||
|
||||
/* tm_type can now be used to represent tm argument types and
|
||||
return types for ffi_prep_cif() */
|
||||
}
|
||||
|
||||
|
||||
File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, Up: Using libffi
|
||||
|
||||
2.4 Multiple ABIs
|
||||
=================
|
||||
|
||||
A given platform may provide multiple different ABIs at once. For
|
||||
instance, the x86 platform has both `stdcall' and `fastcall' functions.
|
||||
|
||||
`libffi' provides some support for this. However, this is
|
||||
necessarily platform-specific.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Closure API, Prev: Multiple ABIs, Up: Using libffi
|
||||
|
||||
2.5 The Closure API
|
||||
===================
|
||||
|
||||
`libffi' also provides a way to write a generic function - a function
|
||||
that can accept and decode any combination of arguments. This can be
|
||||
useful when writing an interpreter, or to provide wrappers for
|
||||
arbitrary functions.
|
||||
|
||||
This facility is called the "closure API". Closures are not
|
||||
supported on all platforms; you can check the `FFI_CLOSURES' define to
|
||||
determine whether they are supported on the current platform.
|
||||
|
||||
Because closures work by assembling a tiny function at runtime, they
|
||||
require special allocation on platforms that have a non-executable
|
||||
heap. Memory management for closures is handled by a pair of functions:
|
||||
|
||||
-- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE)
|
||||
Allocate a chunk of memory holding SIZE bytes. This returns a
|
||||
pointer to the writable address, and sets *CODE to the
|
||||
corresponding executable address.
|
||||
|
||||
SIZE should be sufficient to hold a `ffi_closure' object.
|
||||
|
||||
-- Function: void ffi_closure_free (void *WRITABLE)
|
||||
Free memory allocated using `ffi_closure_alloc'. The argument is
|
||||
the writable address that was returned.
|
||||
|
||||
Once you have allocated the memory for a closure, you must construct
|
||||
a `ffi_cif' describing the function call. Finally you can prepare the
|
||||
closure function:
|
||||
|
||||
-- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE,
|
||||
ffi_cif *CIF, void (*FUN) (ffi_cif *CIF, void *RET, void
|
||||
**ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC)
|
||||
Prepare a closure function.
|
||||
|
||||
CLOSURE is the address of a `ffi_closure' object; this is the
|
||||
writable address returned by `ffi_closure_alloc'.
|
||||
|
||||
CIF is the `ffi_cif' describing the function parameters.
|
||||
|
||||
USER_DATA is an arbitrary datum that is passed, uninterpreted, to
|
||||
your closure function.
|
||||
|
||||
CODELOC is the executable address returned by `ffi_closure_alloc'.
|
||||
|
||||
FUN is the function which will be called when the closure is
|
||||
invoked. It is called with the arguments:
|
||||
CIF
|
||||
The `ffi_cif' passed to `ffi_prep_closure_loc'.
|
||||
|
||||
RET
|
||||
A pointer to the memory used for the function's return value.
|
||||
FUN must fill this, unless the function is declared as
|
||||
returning `void'.
|
||||
|
||||
ARGS
|
||||
A vector of pointers to memory holding the arguments to the
|
||||
function.
|
||||
|
||||
USER_DATA
|
||||
The same USER_DATA that was passed to `ffi_prep_closure_loc'.
|
||||
|
||||
`ffi_prep_closure_loc' will return `FFI_OK' if everything went ok,
|
||||
and something else on error.
|
||||
|
||||
After calling `ffi_prep_closure_loc', you can cast CODELOC to the
|
||||
appropriate pointer-to-function type.
|
||||
|
||||
You may see old code referring to `ffi_prep_closure'. This function
|
||||
is deprecated, as it cannot handle the need for separate writable and
|
||||
executable addresses.
|
||||
|
||||
|
||||
File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top
|
||||
|
||||
3 Missing Features
|
||||
******************
|
||||
|
||||
`libffi' is missing a few features. We welcome patches to add support
|
||||
for these.
|
||||
|
||||
* There is no support for calling varargs functions. This may work
|
||||
on some platforms, depending on how the ABI is defined, but it is
|
||||
not reliable.
|
||||
|
||||
* There is no support for bit fields in structures.
|
||||
|
||||
* The closure API is
|
||||
|
||||
* The "raw" API is undocumented.
|
||||
|
||||
|
||||
File: libffi.info, Node: Index, Prev: Missing Features, Up: Top
|
||||
|
||||
Index
|
||||
*****
|
||||
|
||||
| ||||