2016-09-13 4 views
0

Я пытаюсь проверить код JNI, интегрирующий Java-класс с некоторыми функциями ROS, и я изо всех сил пытаюсь правильно связать Java-методы. У меня есть собственный код, скомпилированный с интерфейсом JNI правильно (или так я думаю), но во время выполнения я получаю UnsatisifiedLinkError по первому встроенному методу, который я определил. На данный момент я не уверен, что основная причина в том, что JVM неправильно загружает файл .so (в том же каталоге, и я пробовал -Djava.library.path=.), или если он успешно загружает его, и он не находит метод правильно.JNI: UnsatisfiedLinkError

Это сообщение об ошибке дает так мало, чтобы продолжить, есть ли способ получить больше информации о том, что именно вызывает его?

Я не против публикации исходного кода, если бы это помогло, хотя мне пришлось бы сделать некоторое редактирование, прежде чем я смогу загрузить его, поэтому я подожду, если вы, ребята, подумаете, что это может быть полезно.

Talker.java:

public class Talker { 
    /** 
    * ROS Native methods 
    * 
    * Simple passthrough to the C++ native methods in the ROS layer 
    */ 
    private static native void rosAdvertise(); 
    private static native void rosPublish(); 
    private static native void rosSpinOnce(); 

    { 
     System.loadLibrary("ros-test-native-talker"); 
    } 

    public static void main(String[] args) { 
     rosAdvertise(); 

     while (true) { 
      rosPublish(); 

      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      rosSpinOnce(); 
     } 
    } 
} 

РОС-тест-нативной talker.cpp:

#include "test_rostest_Talker.h" 
#include "ros/ros.h" 
#include "std_msgs/Time.h" 

ros::Publisher outbound; 


JNIEXPORT void JNICALL Java_test_rostest_Talker_rosAdvertise 
    (JNIEnv *, jclass) { 
    int argc = 0; 
    char **argv; 
    ros::init(argc, argv, "ros-native-timing-tester"); 

    ros::NodeHandle n; 
    outbound = n.advertise<std_msgs::Time>("chatter", 1000); 
} 


JNIEXPORT void JNICALL Java_test_rostest_Talker_rosPublish 
    (JNIEnv *, jclass) { 
    ros::Time tx_timestamp = ros::Time::now(); 

    ROS_INFO("Sending message at %d.%d", tx_timestamp.sec, tx_timestamp.nsec); 

    std_msgs::Time msg; 
    msg.data = tx_timestamp; 

    outbound.publish(msg); 
} 


JNIEXPORT void JNICALL Java_test_rostest_Talker_rosSpinOnce 
    (JNIEnv *, jclass) { 
    ros::spinOnce(); 
} 

и выход:

[email protected]:~/javarostest$ java -Djava.library.path=. -cp ros-test-native-1.0-SNAPSHOT.jar test.rostest.Talker                        
Exception in thread "main" java.lang.UnsatisfiedLinkError: test.rostest.Talker.rosAdvertise()V 
     at test.rostest.Talker.rosAdvertise(Native Method) 
     at test.rostest.Talker.main(Talker.java:21) 
+0

Сообщите нам код, мы сможем вам помочь. – Carlton

+0

Обновление с кодом и выходом консоли –

+0

Я вижу, что вы используете 'System.loadLibrary', который может быть немного придирчивым. В linux файл должен быть назван «libros-test-native-talker.so», а также в окнах «ros-test-native-talker.dll» (или любое другое сопоставление конкретной платформы). Хотя я загружал файлы .so на окна перед использованием 'System.load', который просто принимает абсолютный путь. –

ответ

0

Я понятия не имею, почему, но рефакторинга приведенный выше код слегка заставил его работать. Если я беру собственные методы из основного класса и помещаю их в отдельный класс (таким образом удаляя статический модификатор по собственным методам), который вызывается основным классом, все ссылки и работает нормально. Я не уверен и даже не знаю, почему, но я думаю, что статический модификатор этих методов вызывал некоторые проблемы.

Смежные вопросы