Ich möchte eine Methode aus Performancegründen nativ auslagern. Zu Hause ist mir das auch schon gelungen. Da hab ich allerdings keine packages und statischen Methoden verwendet.
Mein Code:
MUtilities (package: utils)
import [...]
public class MUtilities {
// CONSTANTS
public static final int OVERWRITE_FILES = 0;
public static final int UNCHANGE_EXISTING_FILES = 1;
public static native int countFilesInDirectory( String dir );
private static boolean loadLib = true;
static {
try {
String lib = new File(".").getAbsolutePath() +
File.separatorChar +
"native" +
File.separatorChar +
"counter." +
((System.getProperty("os.name").equals("Linux")) ? "so" : "dll");
System.load( lib );
System.out.println( lib );
} catch ( java.lang.UnsatisfiedLinkError err ) {
loadLib = false;
System.err.println( "Kann Library nicht laden!" );
}
}
[...]
}```
**listing.cpp**
```#include <iostream>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <jni.h>
#include "MUtilities.h"
int count_files( const char* path ) {
DIR* dir;
struct dirent* dirpointer;
if ( (dir=opendir(path)) == NULL ) {
std::cerr << "Verzeichnis konnte nicht geoeffnet werden!" << std::endl;
return 0;
}
int i=0;
char* tmp_file = new char[500];
struct stat* file_info;
while ( (dirpointer=readdir(dir)) != NULL ) {
if ( strcmp(dirpointer->d_name, ".") && strcmp(dirpointer->d_name, "..") ) {
strncpy( tmp_file, path, 450 );
strncat( tmp_file, "/", 1 );
strncat( tmp_file, dirpointer->d_name, 49 );
file_info = new struct stat;
if ( stat(tmp_file, file_info) != -1 && file_info->st_mode & S_IFDIR ) {
i += count_files( tmp_file );
//printf( "%s
", tmp_file );
} else {
i++;
}
delete file_info;
}
}
closedir( dir );
return i;
}
JNIEXPORT jint JNICALL Java_utils_MUtilities_countFilesInDirectory( JNIEnv* env, jclass obj, jstring str ) {
return count_files( env->GetStringUTFChars(str, NULL) );
}```
**MUtilities.h** (generiert durch **javah -jni utils.MUtilities**)
```/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class utils_MUtilities */
#ifndef _Included_utils_MUtilities
#define _Included_utils_MUtilities
#ifdef __cplusplus
extern "C" {
#endif
#undef utils_MUtilities_OVERWRITE_FILES
#define utils_MUtilities_OVERWRITE_FILES 0L
#undef utils_MUtilities_UNCHANGE_EXISTING_FILES
#define utils_MUtilities_UNCHANGE_EXISTING_FILES 1L
/*
* Class: utils_MUtilities
* Method: countFilesInDirectory
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_utils_MUtilities_countFilesInDirectory
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif```
Das Programm lässt sich erfolgreich übersetzen mit
mingw32-g++ -I C:\Programme\Java\jdk1.6.0\include -shared -o counter.dll listing.cpp
Jetzt liegt die Library 'counter.dll' im Verzeichnis 'native' in meinem Hauptprogrammordner.
Beim Programmstart wird die DLL auch erfolgreich geladen, doch beim Aufruf der nativen Methode kommt ein UnsatisfiedLinkError:
Exception in thread “main” java.lang.UnsatisfiedLinkError: utils.MUtilities.countFilesInDirectory(Ljava/lang/String;)I
at utils.MUtilities.countFilesInDirectory(Native Method)
at main.Starter.main(Starter.java:66)
Wo kann da das Problem liegen? :confused: