2017-10-06 2 views
1

J'essaie de développer un plugin pour Fiji/ImageJ qui repose sur une bibliothèque native (JNI). La bibliothèque JNI elle-même dépend de libtiff et de fftw. Sur OSX et Linux, j'utilise la classe NativeUtils et tout fonctionne bien.Encapsulation d'une bibliothèque JNI dans un fichier jar

Sur les fenêtres, je compris des versions binaires de libtiff et fftw dans le paquet CMake et a réussi à lier la bibliothèque JNI contre ceux (soit statiquement de façon dynamique). Toutefois, le module JNI résultant n'inclut pas libtiff ou fftw et j'obtiens une erreur lorsque j'essaie de charger la bibliothèque JNI avec NativeUtils.loadLibraryFromJar. C'est également le cas lorsque j'inclue le .dll dépendant dans le .jar car ils ne sont pas extraits par NativeUtils.

Voici les lignes concernées CMakeLists.txt:

add_library(fftw STATIC IMPORTED GLOBAL) 
set_target_properties(fftw PROPERTIES IMPORTED_LOCATION "${libdir}/libfftw3f-3.lib" 
             INTERFACE_INCLUDE_DIRECTORIES "${incdir}") 

SWIG_ADD_LIBRARY(javainterf 
       TYPE MODULE 
       LANGUAGE java 
       SOURCES javainterf.i javainterf.c src1.c) 
SWIG_LINK_LIBRARIES(javainterf libcode1 fftw) 

add_jar(Foo 
     SOURCES ${CMAKE_CURRENT_BINARY_DIR}/java/foo1.java 
     INCLUDE_JARS java/resources/ij-1.51p.jar 
     VERSION ${JAR_VERSION}) 
add_dependencies(Foo javainterf) 
add_custom_command(TARGET Foo POST_BUILD 
    COMMAND "${Java_JAR_EXECUTABLE}" -uf Foo-${JAR_VERSION}.jar 
    -C ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${JNI_LIB_NAME}) 

Comment voulez-vous faire en sorte que toutes les dépendances sont correctement incluses dans le pot et chargé?

+0

Pas une solution complète, mais avez-vous lu la page [Développement à l'aide de bibliothèques natives] (https://imagej.net/Developing_using_native_libraries) de la documentation ImageJ? Avez-vous essayé de placer votre bibliothèque native dans '$ IJ_ROOT/lib/' au lieu de l'intégrer dans un fichier JAR? – ctrueden

+0

J'y ai pensé mais cela rend l'installation plus compliquée pour l'utilisateur final. Je vais essayer de tout inclure dans le pot si la solution proposée par @mko fonctionne pour moi. – hpixel

+0

Je ne comprends pas votre inquiétude concernant l'installation. Si vous utilisez un [site de mise à jour] (https://imagej.net/Update_Sites), vous pouvez envoyer tous les fichiers dont vous avez besoin à l'utilisateur en cliquant sur un bouton et ils recevront automatiquement les mises à jour. – ctrueden

Répondre

0

Vous ne pouvez pas charger la bibliothèque depuis l'intérieur de JAR sans l'extraire en premier lieu.

Jetez un oeil ici à l'exemple complet où le code natif est intégré dans JAR et extrait si nécessaire.

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo031

Mise à jour

Eh bien, dans ce cas, lorsque vous avez besoin d'emballer plus libs et que vous voulez résoudre correctement les emplacements, vous devez jouer avec l'exécution env un peu.

Jetez un oeil ici:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo035

git clone https://github.com/mkowsiak/jnicookbook 
cd jnicookbook/recipeNo035 
make 
make test 

Amusez-vous avec JNI!

+0

Le problème ici est que j'ai plusieurs bibliothèques dépendantes et un seul est extrait à la fois. Je ne vois pas comment fusionner toutes les dépendances dans un DLL avec cmake. – hpixel

+0

Vous pouvez toujours extraire toutes les bibliothèques et les charger toutes en utilisant System.load. Après tout, c'est juste une question de symboles qui sont chargés depuis les bibliothèques. – mko

+0

Ma bibliothèque jni dépend de certaines bibliothèques partagées non-jni. Même s'ils ne sont pas jni, j'ai essayé de les charger avec 'loadlibraryfromjar', et ça ne marche pas: j'ai la même erreur. – hpixel