Skip to content

Initial documentation in markdown format. #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 17, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
build
build.eclipse
build.number
.metadata
bin
jnalib/contrib/ntservice/dist
jnalib/contrib/platform/dist

479 changes: 479 additions & 0 deletions CHANGES.md

Large diffs are not rendered by default.

File renamed without changes.
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
![Java Native Access - JNA](https://github.com/twall/jna/raw/master/www/images/jnalogo.jpg "Java Native Access - JNA")

Java Native Access (JNA)
========================

JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java code—no JNI or native code is required. This functionality is comparable to Windows' Platform/Invoke and Python's ctypes. Access is dynamic at runtime without code generation.

JNA allows you to call directly into native functions using natural Java method invocation. The Java call looks just like it does in native code. Most calls require no special handling or configuration; no boilerplate or generated code is required.

The JNA library uses a small native library stub to dynamically invoke native code. The developer uses a Java interface to describe functions and structures in the target native library. This makes it quite easy to take advantage of native platform features without incurring the high overhead of configuring and building JNI code for multiple platforms.

While some attention is paid to performance, correctness and ease of use take priority.

JNA includes a platform library with many native functions already mapped as well as a set of utility interfaces that simplify native access.

Features
========

* Automatic mapping from Java to native functions, with simple mappings for all primitive data types
* Runs on most platforms which support Java
* Automatic conversion between C and Java strings, with customizable encoding/decoding
* Structure and Union arguments/return values, by reference and by value
* Function Pointers, (callbacks from native code to Java) as arguments and/or members of a struct
* Auto-generated Java proxies for native function pointers
* By-reference (pointer-to-type) arguments
* Java array and NIO Buffer arguments (primitive types and pointers) as pointer-to-buffer
* Nested structures and arrays
* Wide (wchar_t-based) strings
* Native long support (32- or 64-bit as appropriate)
* Demo applications
* Supported on 1.4 or later JVMs (earlier VMs may work with stubbed NIO support)
* Customizable marshalling/unmarshalling (argument and return value conversions)
* Customizable mapping from Java method to native function name, and customizable invocation to simulate C preprocessor function macros
* Support for automatic Windows ASCII/UNICODE function mappings
* Varargs support
* Type-safety for native pointers
* VM crash protection (optional)
* Optimized direct mapping for high-performance applications.

Community
=========

All questions should be posted ot the [jna-users Google group](http://groups.google.com/group/jna-users). Issues can be submitted [here on Github](https://github.com/twall/jna/issues).

Using the Library
=================

* [Getting Started](jna/tree/master/www/GettingStarted.md)
* [Mapping between Java and Native](jna/tree/master/www/Mappings.md)
* [Using Pointers and Arrays](jna/tree/master/www/PointersAndArrays.md)
* [Using Structures and Unions](jna/tree/master/www/StructuresAndUnions.md)
* [Using By-Reference Arguments](jna/tree/master/www/ByRefArguments.md)
* [Customization](jna/tree/master/www/CustomMappings.md)
* [Callbacks/Closures](jna/tree/master/www/CallbacksAndClosures.md)
* [Dynamically Typed Languages (JRuby/Jython)](jna/tree/master/www/DynamicallyTypedLanguages.md)
* [Platform Library](jna/tree/master/www/PlatformLibrary.md)
* [Direct Method Mapping](jna/tree/master/www/DirectMapping.md)
* [Frequently Asked Questions (FAQ)](jna/tree/master/www/FrequentlyAskedQuestions.md)

Contributing
============

You're encouraged to contribute to JNA. Fork the code from [github.com/twall/jna](https://github.com/twall/jna) and submit pull requests.

If you are interested in paid support, feel free to say so on the [jna-users mailing list](http://groups.google.com/group/jna-users). Most simple questions will be answered on the list, but more complicated work, new features or target platforms can be negotiated with any of the JNA developers (this is how several of JNA's features came into being). You may even encounter other users with the same need and be able to cost share the new development.

License
=======

This library is provided under the LGPL, version 2.1 or later.

*NOTE: Oracle is not sponsoring this project, even though the package name (com.sun.jna) might imply otherwise.*

22 changes: 22 additions & 0 deletions build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<project name="jna" basedir="." default="default">
<target name="recurse">
<ant dir="jnalib" target="${ant.target}" />
</target>
<target name="default">
<antcall target="recurse">
<param name="ant.target" value="default" />
</antcall>
</target>
<target name="clean">
<antcall target="recurse">
<param name="ant.target" value="clean" />
</antcall>
</target>
<target name="test">
<antcall target="recurse">
<param name="ant.target" value="test" />
</antcall>
</target>
</project>

2 changes: 1 addition & 1 deletion jnalib/.project
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>jna</name>
<name>jnalib</name>
<comment></comment>
<projects>
</projects>
Expand Down
2 changes: 1 addition & 1 deletion jnalib/contrib/alphamaskdemo/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="src" path="/platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
2 changes: 1 addition & 1 deletion jnalib/contrib/dnddemo/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="src" path="/platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
4 changes: 2 additions & 2 deletions jnalib/contrib/ntservice/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="build.eclipse/contrib-test-classes" path="test"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/jna"/>
<classpathentry combineaccessrules="false" kind="src" path="/jnalib"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
2 changes: 2 additions & 0 deletions jnalib/contrib/ntservice/test/placeholder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# placeholder

4 changes: 2 additions & 2 deletions jnalib/contrib/platform/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="build.eclipse/contrib-test-classes" path="test"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/jna"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/jnalib"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="output" path="bin"/>
</classpath>
2 changes: 1 addition & 1 deletion jnalib/contrib/shapedwindowdemo/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="src" path="/platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
4 changes: 2 additions & 2 deletions jnalib/contrib/w32keyhook/.classpath
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path=""/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="/jna"/>
<classpathentry kind="src" path="/jnalib"/>
<classpathentry kind="src" path="/platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
4 changes: 2 additions & 2 deletions jnalib/contrib/x11/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/jna"/>
<classpathentry combineaccessrules="false" kind="src" path="/jnalib"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="/jna/dist/jna.jar"/>
<classpathentry kind="lib" path="/jnalib/dist/jna.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/platform"/>
<classpathentry kind="output" path="bin"/>
</classpath>
22 changes: 22 additions & 0 deletions www/ByRefArguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Using ByReference Arguments
===========================

When a function accepts a pointer-to-type argument you can use one of the `ByReference` types to capture the returned value, or subclass your own. For example:

// Original C declaration
void allocate_buffer(char **bufp, int* lenp);

// Equivalent JNA mapping
void allocate_buffer(PointerByReference bufp, IntByReference lenp);

// Usage
PointerByReference pref = new PointerByReference();
IntByReference iref = new IntByReference();
lib.allocate_buffer(pref, iref);
Pointer p = pref.getValue();
byte[] buffer = p.getByteArray(0, iref.getValue());

Alternatively, you could use a Java array with a single element of the desired type, but the `ByReference` convention better conveys the intent of the code. The `Pointer` class provides a number of accessor methods in addition to `getByteArray()` which effectively function as a typecast onto the memory.

Type-safe pointers may be declared by deriving from the `PointerType` class.

62 changes: 62 additions & 0 deletions www/CallbacksAndClosures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Callbacks and Closures
======================

Callback declarations consist of a simple interface that extends the Callback interface and implements a callback method (or defines a single method of arbitrary name). Callbacks are implemented by wrapping a Java object method in a little bit of C glue code. The simplest usage resembles using anonymous inner classes to register event listeners. Following is an example of callback usage:

// Original C declarations
typedef void (*sig_t)(int);
sig_t signal(sig_t);

// Equivalent JNA mappings
public interface CLibrary extends Library {
int SIGUSR1 = 30;
interface sig_t extends Callback {
void invoke(int signal);
}
sig_t signal(int sig, sig_t fn);
int raise(int sig);
}
...
CLibrary lib = (CLibrary)Native.loadLibrary("c", CLibrary.class);
// WARNING: you must keep a reference to the callback object
// until you deregister the callback; if the callback object
// is garbage-collected, the native callback invocation will
// probably crash.
CLibrary.sig_t fn = new CLibrary.sig_t() {
public void invoke(int sig) {
System.out.println("signal " + sig + " was raised");
}
};
CLibrary.sig_t old_handler = lib.signal(CLibrary.SIGUSR1, fn);
lib.raise(CLibrary.SIGUSR1);
...

Here is a more involved example, using the Win32 APIs to enumerate all native windows:

// Original C declarations
typedef int (__stdcall *WNDENUMPROC)(void*,void*);
int __stdcall EnumWindows(WNDENUMPROC,void*);

// Equivalent JNA mappings
public interface User32 extends StdCallLibrary {
interface WNDENUMPROC extends StdCallCallback {
/** Return whether to continue enumeration. */
boolean callback(Pointer hWnd, Pointer arg);
}
boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);
}
...
User32 user32 = User32.INSTANCE;

user32.EnumWindows(new WNDENUMPROC() {
int count;
public boolean callback(Pointer hWnd, Pointer userData) {
System.out.println("Found window " + hWnd + ", total " + ++count);
return true;
}
}, null);

If your callback needs to live beyond the method invocation where it is used, make sure you keep a reference to it or the native code will call back to an empty stub after the callback object is garbage collected.

Proxy wrappers are automatically generated for function pointers found within structs initialized by native code. This facilitates calling those functions from Java.

9 changes: 9 additions & 0 deletions www/CustomMappings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Customized Mapping from Java to Native
======================================

The `TypeMapper` class and related interfaces provide for converting any Java type used as an argument, return value, or structure member to be converted to or from a native type. The example Win32 API interfaces use a type mapper to convert Java boolean into the Win32 BOOL type. A TypeMapper instance is passed as the value for the `TYPE_MAPPER` key in the options map passed to `Native.loadLibrary`.

Alternatively, user-defined types may implement the `NativeMapped` interface, which determines conversion to and from native types on a class-by-class basis.

You may also customize the mapping of Java method names to the corresponding native function name. The `StdCallFunctionMapper` is one implementation which automatically generates stdcall-decorated function names from a Java interface method signature. The mapper should be passed as the value for the `OPTION_FUNCTION_MAPPER` key in the options map passed to the `Native.loadLibrary` call.

24 changes: 24 additions & 0 deletions www/DirectMapping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Direct Mapping
==============

JNA supports a direct mapping method which can improve performance substantially, approaching that of custom JNI. Method signatures are the same as they would be in a JNA interface mapping, but they can be any static or object methods. You only need register them within the static initializer of the defining class, as in the example below. The `Native.register()` method takes the name of your native library, the same as Native.loadLibrary() would.

import com.sun.jna.*;

public class HelloWorld {

static {
Native.register(Platform.isWindows() ? "msvcrt" : "m");
}

public static native double cos(double);
public static native double sin(double);

public static void main(String[] args) {
System.out.println("cos(0)=" + cos(0));
System.out.println("sin(0)=" + sin(0));
}
}

Direct mapping supports the same type mappings as interface mapping, except for arrays of Pointer/String/WString/NativeMapped as function arguments. You can easily convert from interface mapping to direct mapping by creating a direct mapping class which implements your library interface, with all methods defined as native methods. Then your library instance variable can be assigned an instance of this new class instead of the object returned by `Native.loadLibrary()`.

37 changes: 37 additions & 0 deletions www/DynamicallyTypedLanguages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Dynamically Typed Languages
===========================

Languages such as Jython or JRuby may find it more convenient to access the `NativeLibrary` and Function classes directly rather than establishing a dedicated interface.
Here's a brief example of using JNA from JRuby:

require 'java'

module Libc
@@lib = com.sun.jna.NativeLibrary.getInstance("c")
@@ptr_funcs = [ 'fopen', 'malloc', 'calloc' ]
def self.method_missing(meth, *args)
if @@ptr_funcs.include?(meth.to_s)
@@lib.getFunction(meth.to_s).invokePointer(args.to_java)
else
@@lib.getFunction(meth.to_s).invokeInt(args.to_java)
end
end
O_RDONLY = 0
O_WRONLY = 1
O_RDWR = 2
end

Libc.puts("puts from libc")
Libc.printf("Hello %s, from printf\n", "World")

file = Libc.open("/dev/stdout", 1, Libc::O_WRONLY)
n = Libc.write(file, "Test\n", 5)
puts "Wrote #{n} bytes via Libc"

path = "/dev/stdout"
fp = Libc.fopen(path, "w+")
Libc.fprintf(fp, "fprintf to %s via stdio\n", path)
Libc.fflush(fp)
Libc.fclose(fp)


Loading