Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > JNI & UnsatisfiedLinkError


Автор: Metal_Heart 19.4.2006, 13:25
О Великий форум!
У меня возникла такая проблема с JNI:

Код

public class ComPort
{
//-----------------------------------------------------------------
static
{
 System.loadLibrary("ComPort");
}
//-----------------------------------------------------------------
public  native int  showMessage();       // -  любопытства ради
private native int  closePort(int port);
//-----------------------------------------------------------------
public int portClose(int port)
{
int i=0;
 try{i=closePort(port);}catch(Exception e){System.out.println("(Java::CommPort) Err:closePort("+port+")");}
return i;
}
//-----------------------------------------------------------------
public static void main(String[] str)
{
int i;
int numPort = 4;

 ComPort comPort = new ComPort();
 i=comPort.showMessage();                    System.out.println("(Java::ComPort) showMessage value: \t"+i);
 i=comPort.portClose(numPort);               System.out.println("(Java::ComPort) port is closed? \t"+i);
}
//-----------------------------------------------------------------


в результате имею ВОТ ТАКУЮ ошибку, млин:
Код

(Cpp::ComPort) it's message!
(Java::ComPort) showMessage value:    1

Exception in thread "main" java.lang.UnsatisfiedLinkError: closePort
    at ComPort.closePort(Native Method)
    at ComPort.portClose(ComPort.java:45)
    at ComPort.main(ComPort.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)


вот нативный код [header]:
Код

/*
 * Class:     ComPort
 * Method:    showMessage
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_ComPort_showMessage
  (JNIEnv *, jobject);

/*
 * Class:     ComPort
 * Method:    closePort
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_ComPort_closePort
  (JNIEnv *, jobject, jint);


вот нативный код [source]:
Код

//------------------------------------------------------------------------------
JNIEXPORT jint JNICALL Java_ComPort_showMessage(JNIEnv *, jobject)
{
 printf("(Cpp::ComPort) it's message!\n");

return 1;
}
//------------------------------------------------------------------------------
JNIEXPORT jint JNICALL Java_CommPort_closePort(JNIEnv * jenv, jobject jobj, jint port)
{if(!init) Init();

return ClosePort(port);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unsigned int ClosePort(unsigned int port)
{if(!comport) return PORT_CLOSE;

 printf("(Cpp::ComPort) close port: \t%d\n",port);
 try{if(comport->CloseCOMport()!=PORT_CLOSE) {printf("(Cpp::ComPort) Can't close this port: \t%d\n",port); return PORT_ERROR;}}
   catch(...){printf("(Cpp::ComPort) Exeption: closing port: \t%d\n",port); return PORT_ERROR;}

 comport=0;

return PORT_CLOSE;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


а самое обидное то, что пока я не влез дорабатывать эти исходники (которые сам и писал) оно работало, ёпрст
 

Автор: LSD 19.4.2006, 14:05
У тебя в Java классе объявлен метод portClose, а в заголовочном файле Java_ComPort_closePort, естественно он не может найти его. 

Автор: Metal_Heart 19.4.2006, 14:07
шутить изволите?

Цитата(Metal_Heart @  19.4.2006,  13:25 Найти цитируемый пост)

//-----------------------------------------------------------------
static
{
 System.loadLibrary("ComPort");
}
//-----------------------------------------------------------------
public  native int  showMessage();       // -  любопытства ради
private native int  closePort(int port);
//-----------------------------------------------------------------

 

Автор: val 19.4.2006, 14:07
Не уверен, но мне кажется, что почему-то имеет место конфликт имён, у тебя есть С++ функция ClosePort, которую нельзя дернуть из Java и вместе с тем, есть java-функция  closePort. Попробый как-то по разному их называть. 

Автор: Metal_Heart 19.4.2006, 14:11
val, я, конечно, был уверен, что не это, но проверил - ничего не изменилось
 

Автор: Metal_Heart 19.4.2006, 14:26
использую JDk1.5.0_06

и чуток упростил Java-код:
Код

public class ComPort
{
//-----------------------------------------------------------------
static
{
 System.loadLibrary("ComPort");
}
//-----------------------------------------------------------------
public  native int  showMessage();       // -  любопытства ради
public  native int  closePort(int port);
//-----------------------------------------------------------------
public static void main(String[] str)
{
int i;
int numPort = 4;
 ComPort comPort = new ComPort();
 i=comPort.showMessage();                    System.out.println("(Java::ComPort) showMessage value: \t"+i);
 i=comPort.closePort(numPort);               System.out.println("(Java::ComPort) port is closed? \t"+i);
}
//-----------------------------------------------------------------
 

Автор: Metal_Heart 19.4.2006, 15:23
Докладываю:

Проект был ранее откомпилирован, создан JAR-ик отправлен в JDK/JRE/LIB/EXT/ и подключен к IDE,
в результате чего javah не мог (или не хотел) создавать обнавленный header-файл для С++

т.е. 
Код

//-----------------------------------------------------------------
static
{
 System.loadLibrary("ComPort");
}
//-----------------------------------------------------------------
public  native int  showMessage(int a, int b);       // -  любопытства ради
//  !закоментировано!     private native int  closePort(int port);
//-----------------------------------------------------------------


header всё равно имел вид:
Код

/*
 * Class:     ComPort
 * Method:    showMessage
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_ComPort_showMessage
  (JNIEnv *, jobject);
/*
 * Class:     ComPort
 * Method:    closePort
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_ComPort_closePort
  (JNIEnv *, jobject, jint);


Это была проблема №1 - решилась удалением вышеупомянутого JAR-ика как из упоминания в IDE, так и заодно из JDK/JRE/LIB/EXT/ 
Проблема №2 - человеческий фактор, который довольно трудно сразу увидеть:

вот нативный код [header]:
Код

JNIEXPORT jint JNICALL Java_ComPort_closePort ( ...



вот нативный код [source]:
Код

JNIEXPORT jint JNICALL Java_Co[m]mPort_closePort( ...




Так то, вот.  smile  И спасибо всем   

Автор: LSD 19.4.2006, 16:04
Цитата(Metal_Heart @  19.4.2006,  15:07 Найти цитируемый пост)
шутить изволите?

Нет, просто перепутал функции. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)