Call a function in a shared library: Difference between revisions

→‎{{header|Java}}: Expand JNI example. It now has C code for a library, and continues if the library is missing.
(→‎{{header|Ruby}}: Believe that I need Ruby 2.0 for Fiddle::Importer, and Ruby 1.9 for String#force_encoding.)
(→‎{{header|Java}}: Expand JNI example. It now has C code for a library, and continues if the library is missing.)
Line 881:
 
=={{header|Java}}==
TheFor methods with the <tt>native</tt> keyword is the key here. For this method, the library must be written to the [[wp:Java Native Interface|Java Native Interface]]; this is not a general [[FFI]]. If the library is missing, <code>System.loadLibrary()</code> throws <code>UnsatisfiedLinkError</code>. We can continue if we catch this error and then don't call the library's native methods.
<lang java>public class LoadLib{
private static native void functionInSharedLib(); //change return type or parameters as necessary
 
If you have Unix [[make]], then edit the ''Makefile'', run <code>make</code>, run <code>java -Djava.library.path=. RSort</code>. If you don't set java.library.path, or don't build the library, then the Java code falls back from using C to using Java. For more info about building a JNI library, see [[Call a foreign-language function#Java]].
public static void main(String[] args){
 
System.loadLibrary("Path/to/library/here/lib.dll");
<lang java>/* RSort.java -- reverse sort of random integers */
functionInSharedLib();
 
}
import java.util.Collections;
import java.util.Random;
 
public class RSort {
static boolean useC;
static {
try {
System.loadLibrary("RSort");
useC = true;
} catch(UnsatisfiedLinkError e) {
useC = false;
}
}
static native void sortInC(int[] ary);
static class IntList extends java.util.AbstractList<Integer> {
int[] ary;
IntList(int[] ary) { this.ary = ary; }
public Integer get(int i) { return ary[i]; }
public Integer set(int i, Integer j) {
Integer o = ary[i]; ary[i] = j; return o;
}
public int size() { return ary.length; }
}
static void sortInJava(int[] ary) {
Collections.sort(new IntList(ary),
Collections.reverseOrder());
}
 
public static void main(String[] args) {
/* Create an array of random integers. */
int[] ary = new int[1000000];
Random rng = new Random();
for (int i = 0; i < ary.length; i++)
ary[i] = rng.nextInt();
 
/* Do the reverse sort. */
if (useC) {
System.out.print("Sorting in C... ");
sortInC(ary);
} else {
System.out.print
("Missing library for C! Sorting in Java... ");
sortInJava(ary);
}
 
for (int i = 0; i < ary.length - 1; i++) {
if (ary[i] < ary[i + 1]) {
System.out.println("*BUG IN SORT*");
System.exit(1);
}
}
System.out.println("ok");
}
}</lang>
 
<lang c>/* RSort.c -- reverse sort of a Java int[] */
 
#include <stdlib.h>
#include "RSort.h"
 
static void fail(JNIEnv *jenv, const char *error_name) {
jclass error_class = (*jenv)->FindClass(jenv, error_name);
(*jenv)->ThrowNew(jenv, error_class, NULL);
}
 
static int reverse_cmp(const void *pa, const void *pb) {
jint a = *(jint *)pa;
jint b = *(jint *)pb;
return a < b ? 1 : a > b ? -1 : 0;
}
 
void Java_RSort_sortInC(JNIEnv *jenv, jclass obj, jintArray ary) {
jint *elem, length;
 
if (ary == NULL) {
fail(jenv, "java/lang/NullPointerException");
return;
}
length = (*jenv)->GetArrayLength(jenv, ary);
elem = (*jenv)->GetPrimitiveArrayCritical(jenv, ary, NULL);
if (elem == NULL) {
fail(jenv, "java/lang/OutOfMemoryError");
return;
}
qsort(elem, length, sizeof(jint), reverse_cmp);
(*jenv)->ReleasePrimitiveArrayCritical(jenv, ary, elem, 0);
}</lang>
 
<lang make># Makefile
 
# Edit the next lines to match your JDK.
JAVA_HOME = /usr/local/jdk-1.8.0
CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/openbsd
JAVAC = $(JAVA_HOME)/bin/javac
JAVAH = $(JAVA_HOME)/bin/javah
 
CC = cc
LDFLAGS = -shared -fPIC
 
all: RSort.class libRSort.so
 
libRSort.so: RSort.c RSort.h
$(CC) $(CPPFLAGS) $(LDFLAGS) -o $@ RSort.c
 
.SUFFIXES: .class .java .h
.class.h:
$(JAVAH) -jni -o $@ $(<:.class=)
touch $@
.java.class:
$(JAVAC) $<
 
clean:
rm -f RSort.class RSort$IntList.class RSort.h libRSort.so</lang>
 
===JNA===
{{libheader|JNA}}
<lang java>import com.sun.jna.Library;
Anonymous user