2016-09-13 4 views
0

자바 클래스를 일부 ROS 기능과 통합 한 일부 JNI 코드를 테스트하려고하는데 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(); 
     } 
    } 
} 

ROS-테스트 네이티브 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'를 사용하고있는 것을 보았습니다. 다소 까다로울 수 있습니다. 리눅스에서이 파일의 이름은 "libros-test-native-talker.so"이어야하고 "ros-test-native-talker.dll"(또는 다른 플랫폼 별 매핑과 상관없이)이어야합니다. 비록 System.load를 사용하기 전에 .so 파일을 윈도우에로드했지만 절대 경로 만 사용합니다. –

답변

0

나는 단서 왜하지만 리팩토링이 없다 위의 코드는 약간의 동작을 야기했습니다. 네이티브 메소드를 기본 클래스에서 가져 와서 기본 클래스에서 호출하는 별도의 클래스에 넣으므로 (기본 메소드에서 정적 수정자를 제거함) 모든 링크가 제대로 작동합니다. 나는 확신 할 수 없으며, 심지어 그 이유에 대한 단서를 가지고있다. 그러나 그 방법들에 정적 수정 자 (static modifier)가 몇 가지 문제를 일으키고 있다고 생각한다.

관련 문제