PJSip账户注册

时间:2013-10-10 20:38:51

标签: android pjsip

我正在尝试将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

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

对此事的任何帮助都会很棒。 感谢

PJ代码

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. sudo make install

  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库
  9. 创建jni文件夹
  10. 运行ndk-build(How to load another .so file in your android project?
  11. 添加到ADT
  12. 关闭项目。将原生支持从Java更改为Android。打开项目 (Convert existing project into Android project in Eclipse?
  13. 将该项目添加到我的TestPJ项目(Android -> Library -> Add
  14. 调用System.loadLibrary("pjsualib") - 新lib.so
  15. 的名称
  16. 收到错误

    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)

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

2 个答案:

答案 0 :(得分:3)

可以找到一个从Java和C中探索JNI调用的项目示例here 问题中提到的错误(java.lang.UnsatisfiedLinkError:找不到本机方法:org.pjsip.pjsua.pjsuaJNI)表示存在以下问题之一:

- 错误的本机方法名称或/及其参数/返回值。如果您可以访问库的本机代码,则可以修复它。根据错误消息和JNI注意事项,本机方法必须具有名称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 Documentation to Java 6 JNI(如果您使用的是android 4.4,则可以找到Java 7)。

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

另外要使用方法pjsip库必须在Java类的某个静态部分中加载System.loadLibrary()
不幸的是,这个问题在运行时发生(如果它在编译期间发生会很好。)

答案 1 :(得分:0)

有点晚了,但我会尽力帮忙。我认为你的问题应该与你的本地方法有关,而不是被extern "C"{}包围并且在C ++中命名为mangling。

如果你没有将一个本地C函数声明为extern "C",那么C ++构建会破坏它并且JNI机制无法找到提供签名的本机方法匹配。另一方面,将构建器声明为外部C函数,构建器会同时创建受损和未受管理的版本,JNI可以找到合适的版本。

希望这会有所帮助。

相关问题