JAVA调用SO文件报UnsatisfiedLinkError

Alan_Chen_2011 2014-11-10 06:54:04
今天使用JNI接口,JAVA调用C编写的SO文件,但是屡次报这个错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Comm.getMsgOut()Ljava/lang/String;
at Comm.getMsgOut(Native Method)
at Comm.main(Comm.java:9)

在CentOS系统下生成libComm.so文件,命令是:
gcc -fpic -shared -I /usr/java/jdk1.8.0_25/include -I /usr/java/jdk1.8.0_25/include/linux Comm.c -o libComm.so

//Comm.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_read_Comm */
#ifndef _Included_com_test_read_Comm
#define _Included_com_test_read_Comm
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_test_read_Comm
* Method: getMsgOut
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_testread_Comm_getMsgOut
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif


//Comm.c

#include <stdio.h>
#include <string.h>
#include <jni.h>
#include "Comm.h"

//char* to jstring
jstring stoJstring(JNIEnv* env, const char* pat)
{
jclass strClass = (*env)->FindClass(env, "Ljava/lang/String;");
jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat));
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = (*env)->NewStringUTF(env, "utf-8");
return (jstring)(*env)->NewObject(env, strClass, ctorID, bytes, encoding);
}

JNIEXPORT jstring JNICALL _Java_com_test_read_Comm_getMsgOut
(JNIEnv *env, jobject obj)
{
unsigned char* msg = "this is SO file";
printf("%s\n", msg);
return stoJstring(env, msg);
}


//Comm.java

class Comm
{
private native static String getMsgOut();
public static void main(String[] args)
{
try{
Comm test = new Comm();
System.out.println(test.getMsgOut());
}catch(Exception ex){
System.out.println("错了");
}
}
static
{
System.loadLibrary("Comm");
}
}


找了半天找不出问题,向大神求助,libComm.so文件是可以被加载的,只是在运行getMsgOut方法时,总是无法linker
...全文
437 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Alan_Chen_2011 2014-11-11
  • 打赏
  • 举报
回复
引用 7 楼 ForestDB 的回复:
http://wenku.baidu.com/link?url=iZW31aQI7Zr5lc9Hs5VYBf50lAP9ZKHGx6IUj_qXoQWaDXey_6Xv9_cCiMlJc5W_ubpuETYZmaX_n4ZLMsqmJADgzkQlvMF6l-OdYj43SVu 随便搜的。 https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
感谢ForestDB,已经搞定了,原因有两点: 1、JAVA和android的虚拟环境不一样 2、Linux和android的系统库文件不一样 这样导致了在Linux下通过JNI标准命名方式编译的SO文件,在android是调用失败的,原因是Linux和android的系统库不一样,而生产的SO跟生产环境库文件有依赖关系 然后搭建了NDK和Cywin环境,然后生产的SO可以被android调用,参考地址: http://zctya.blog.163.com/blog/static/1209178201181074018603/
ForestDB 2014-11-10
  • 打赏
  • 举报
回复
http://wenku.baidu.com/link?url=iZW31aQI7Zr5lc9Hs5VYBf50lAP9ZKHGx6IUj_qXoQWaDXey_6Xv9_cCiMlJc5W_ubpuETYZmaX_n4ZLMsqmJADgzkQlvMF6l-OdYj43SVu 随便搜的。 https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
Alan_Chen_2011 2014-11-10
  • 打赏
  • 举报
回复
引用 5 楼 ForestDB 的回复:
应该不可以,搜个靠谱的吧 一个类的完整名称(包括包名),会影响到生成的native code的函数签名,而linker也是靠名字来的。
JNI的方法名命名规则是JNI通过包名,找类名,再找到方法名,然后加载运行,而你说的没有包名就找不到类名,或者不认识包名?然后就无法link,是这个意思吗? 你是否有好的文章推荐
ForestDB 2014-11-10
  • 打赏
  • 举报
回复
应该不可以,搜个靠谱的吧 一个类的完整名称(包括包名),会影响到生成的native code的函数签名,而linker也是靠名字来的。
Alan_Chen_2011 2014-11-10
  • 打赏
  • 举报
回复
引用 3 楼 ForestDB 的回复:
LZ贴的代码不全吧? 没有package 为何生成的函数签名有包的样子?
你说Comm.java吗?这个我是从根据网上的操作流程自己copy上去的,因为是JAVA调用,没用包名,这个应该可以吧,不然该如何修改?
ForestDB 2014-11-10
  • 打赏
  • 举报
回复
LZ贴的代码不全吧? 没有package 为何生成的函数签名有包的样子?
Alan_Chen_2011 2014-11-10
  • 打赏
  • 举报
回复
@u013163178,呃,C这块也有涉及吧
li4c 2014-11-10
  • 打赏
  • 举报
回复
java怎么发到c论坛了,是不是邀请错人啦,我不会啊

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧