6

我正在尝试将 PJSip 添加到我正在处理的项目中。我有这种方法来注册我的帐户,但每次都会出现“致命信号 11”错误。

这是方法

public int setRegistration() {
    int status = pjsuaConstants.PJ_FALSE;
    /* Register to SIP server by creating SIP account. */
    int[] accId = new int[1];
    accId[0] = 1;

    String uName = getUserName();
    String passwd = getPassword();
    String server = getSIPServer();

    pjsua_acc_config acc_cfg = new pjsua_acc_config();
    pjsua.acc_config_default(acc_cfg);

    acc_cfg.setId(pjsua.pj_str_copy("sip:" + uName + "@" + server));
    acc_cfg.setReg_uri(pjsua.pj_str_copy("sip:" + server));
    acc_cfg.setCred_count(1);

    acc_cfg.getCred_info().setRealm(pjsua.pj_str_copy(server));
    acc_cfg.getCred_info().setScheme(pjsua.pj_str_copy("digest"));
    acc_cfg.getCred_info().setUsername(pjsua.pj_str_copy(uName));
    acc_cfg.getCred_info().setData_type(pjsip_cred_data_type.PJSIP_CRED_DATA_PLAIN_PASSWD.swigValue());
    acc_cfg.getCred_info().setData(pjsua.pj_str_copy(passwd));

    Log.d("status", "acc is adding..");
    status = pjsua.acc_add(acc_cfg, pjsuaConstants.PJ_TRUE, accId);
    Log.d("status", "acc is added");

    if (status == pjsuaConstants.PJ_SUCCESS) {
        status = pjsua.acc_set_online_status(accId[0], 1);
        Log.d("acc_set_online_status returned stauts=", String.valueOf(status));
    } else {
        Log.d("Error status=", String.valueOf(status));
    }
    return status;
}

我在线收到错误status = pjsua.acc_add(acc_cfg, pjsuaConstants.PJ_TRUE, accId);。我知道用户名、服务器和密码不为空。我已经查看了与此相关的多个问题,但没有用。

如何注册我的帐户?

谢谢

*****EDIT****** 在通过博客和论坛追踪到这个之后,我通过了这个错误,但收到了另一个错误。发生此错误的原因是因为pjsua_init从未成功。它成功了,因为它给了我这个错误

11-04 10:19:20.973: E/AndroidRuntime(2961): FATAL EXCEPTION: main
11-04 10:19:20.973: E/AndroidRuntime(2961): java.lang.UnsatisfiedLinkError: Native method not found: org.pjsip.pjsua.pjsuaJNI.init:(JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I
11-04 10:19:20.973: E/AndroidRuntime(2961):     at org.pjsip.pjsua.pjsuaJNI.init(Native Method)
11-04 10:19:20.973: E/AndroidRuntime(2961):     at org.pjsip.pjsua.pjsua.init(pjsua.java:812)

我也收到了这个警告

No implementation found for native Lorg/pjsip/pjsua/pjsuaJNI;.init (JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I

为什么这不是本机方法?我正在查看我调用的库,但除此之外我不知道为什么这不起作用。

在这个问题上的任何帮助都会很棒。谢谢

睡衣代码

pjsua.java

public synchronized static int init(pjsua_config ua_cfg, pjsua_logging_config log_cfg, pjsua_media_config media_cfg) {
   return pjsuaJNI.init(pjsua_config.getCPtr(ua_cfg), ua_cfg, pjsua_logging_config.getCPtr(log_cfg), log_cfg, pjsua_media_config.getCPtr(media_cfg), media_cfg);
}

pjsuaJNI.java

public final static native int init(long jarg1, pjsua_config jarg1_, long jarg2, pjsua_logging_config jarg2_, long jarg3, pjsua_media_config jarg3_);

pjsua_wrap.cpp

SWIGEXPORT jint JNICALL Java_org_pjsip_pjsua_pjsuaJNI_init(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) {
   jint jresult = 0 ;
   pjsua_config *arg1 = (pjsua_config *) 0 ;
   pjsua_logging_config *arg2 = (pjsua_logging_config *) 0 ;
   pjsua_media_config *arg3 = (pjsua_media_config *) 0 ;
   pj_status_t result;

   (void)jenv;
   (void)jcls;
   (void)jarg1_;
   (void)jarg2_;
   (void)jarg3_;
   arg1 = *(pjsua_config **)&jarg1;
   arg2 = *(pjsua_logging_config **)&jarg2;
   arg3 = *(pjsua_media_config **)&jarg3;

   result = (pj_status_t)pjsua_init((pjsua_config const *)arg1,(pjsua_logging_config const *)arg2,(pjsua_media_config const *)arg3);
   jresult = (jint)result;
   return jresult;
}

{"init", "(JLorg/pjsip/pjsua/pjsua_config;JLorg/pjsip/pjsua/pjsua_logging_config;JLorg/pjsip/pjsua/pjsua_media_config;)I", (void*)& Java_org_pjsip_pjsua_pjsuaJNI_init},

编辑 2

因此,在完成此工作后,我感到沮丧。我没有看到我做错了什么,所以我会把我的整个过程放在这里,看看是否有人有建议。

  1. 我首先获取 pjsip 库:svn co http://svn.pjsip.org/repos/pjproject/trunk pjproject
  2. 运行`./configure --prefix=/usr/local
  3. 制作 dep 制作
  4. 须藤使安装

  5. 然后我得到 pjjni 代码svn checkout svn://svn.code.sf.net/p/pjsip-jni/code/ pjsip-jni-code

  6. 我遵循 Makefile 说明
  7. Makefile 成功运行后(经过一些代码清理)我有 2 个 .so 文件(libpjsua_jni.so 和 libpjsua_jni_x64.so)
  8. 使用 Android.mk 文件和 .so 库创建 jni 文件夹
  9. 运行 ndk-build(如何在你的 android 项目中加载另一个 .so 文件?
  10. 添加到 ADT
  11. 关闭项目。将原生支持从 Java 更改为 Android。打开项目(在 Eclipse 中将现有项目转换为 Android 项目?
  12. 将该项目添加到我的 TestPJ 项目 ( Android -> Library -> Add)
  13. 调用System.loadLibrary("pjsualib")——新 lib.so 的名称
  14. 接收错误

    11-22 13:55:44.784: W/dalvikvm(11464): 找不到本地 Lorg/pjsip/pjsua/pjsuaJNI 的实现;.swig_module_init:()V 11-22 13:55:48.792: W/dalvikvm(11464) : 异常 Ljava/lang/UnsatisfiedLinkError; 初始化 Lorg/pjsip/pjsua/pjsuaJNI 时抛出;11-22 13:55:51.417: E/AndroidRuntime(11464): java.lang.UnsatisfiedLinkError: 找不到本机方法: org.pjsip.pjsua.pjsuaJNI.swig_module_init:()V 11-22 13:55:51.417: E /AndroidRuntime(11464): at org.pjsip.pjsua.pjsuaJNI.swig_module_init(Native Method) 11-22 13:55:51.417: E/AndroidRuntime(11464): at org.pjsip.pjsua.pjsuaJNI.(pjsuaJNI.java: 1450)

任何帮助都会很棒。谢谢!

4

2 回答 2

3

可以在此处找到一个探索 Java 和 C 的 JNI 调用的项目示例。
问题中提到的错误(java.lang.UnsatisfiedLinkError: Native method not found: org.pjsip.pjsua.pjsuaJNI)表示以下问题之一:

-错误的本地方法名称或/及其参数/返回值。如果您有权访问库的本机代码,则可以修复它。根据错误消息和 JNI 考虑,native 方法必须具有名称 Java_org_pjsip_pjsua_pjsuaJNI_init(JNIEnv *env, jobject obj, ..),其中 env 是指向 JVM 接口的指针,obj 是“this”指针,其余参数可以从org.pjsip.pjsua 包的pjsuaJNI 类的java init 方法。简单的参数类型必须是 jint、jstring 等。返回值也必须正确。修复所有这些允许从 pjsuaJNI 类中使用此方法。可以从 Oracle 文档到Oracle 文档到 Java 6 JNI(或 Java 7,如果您使用的是 android 4.4)中找到更多详细信息。

-错误的 java 方法名/签名/类名或包名. 这种情况与第一种情况几乎相反。再次,根据提到的错误方法名必须是“init”,类名pjsuaJNI和包org.pjsip.pjsua。如果其中至少一个是错误的,就会发生上述异常。签名或参数也必须正确。在这个错误的边界上,它可以被认为是方法的一个参数(此外在原生的 JNIEnv* 和 jobject 中也会出现)。因此,必要时也必须进行检查和修复。
在从本机代码调用 java 签名的情况下,可以认为是 java 方法的表示,参数为字符串,可以通过应用于 java *.class 文件的 javap -s *.class 命令查看。在来自问题的最后一个警告中,可以看到该方法的签名。

还必须使用方法 pjsip 库加载Java 类的一些静态部分中的 System.loadLibrary() 。

不幸的是,这个问题发生在运行时(如果它发生在编译时就好了)。

于 2013-11-05T19:04:14.100 回答
0

有点晚了,但我会尽力提供帮助。我认为您的问题应该与您的本机方法有关,而不是extern "C"{}在 C++ 中被名称修饰所包围。

如果您不将一个本地 C 函数声明为extern "C",则 C++ 构建会破坏它,并且 JNI 机制无法找到与提供的签名匹配的本地方法。另一方面,将其声明为外部 C 函数,构建器创建了已损坏和未损坏的版本,JNI 可以找到合适的版本。

希望这可以帮助。

于 2013-11-15T21:15:48.307 回答