2013-05-13 89 views
8

有沒有一種方法可以使用和調用從C編譯的庫(如PJSIP庫)中的方法調用?如何在java上使用C庫(例如PJSIP)?

我想使用和調用從我編譯的pjsip庫調用,但顯而易見的問題是,pjsip是一個C庫而不是一個Java庫,即一個jar文件。

可能嗎?也許JNI?

感謝

編輯:使用痛飲試圖做手頭的工作,但它的作用是創建一個空的類文件。

這裏是我用來執行痛飲命令:從痛飲命令

Language subdirectory: java 
Search paths: 
    .\ 
    .\swig_lib\java\ 
    C:\Users\jonney\Downloads\swigwin-2.0.9\Lib\java\ 
    .\swig_lib\ 
    C:\Users\jonney\Downloads\swigwin-2.0.9\Lib\ 
Preprocessing... 
Starting language-specific parse... 
Processing types... 
C++ analysis... 
Generating wrappers... 

pjsua Java類輸出

swig -verbose -java -package com.josh.sip.util -o jni_wrapper.c pjsua.i 

它創造了我:

/* ---------------------------------------------------------------------------- 
* This file was automatically generated by SWIG (http://www.swig.org). 
* Version 2.0.9 
* 
* Do not make changes to this file unless you know what you are doing--modify 
* the SWIG interface file instead. 
* ----------------------------------------------------------------------------- */ 

package com.josh.sip.util; 

public class pjsua { 
} 

的pjsua JNI它爲我創建的文件

/* ---------------------------------------------------------------------------- 
* This file was automatically generated by SWIG (http://www.swig.org). 
* Version 2.0.9 
* 
* Do not make changes to this file unless you know what you are doing--modify 
* the SWIG interface file instead. 
* ----------------------------------------------------------------------------- */ 

package com.josh.sip.util; 

public class pjsuaJNI { 
} 

它生成我下面的jni_wrapper.c:

/* ---------------------------------------------------------------------------- 
* This file was automatically generated by SWIG (http://www.swig.org). 
* Version 2.0.9 
* 
* This file is not intended to be easily readable and contains a number of 
* coding conventions designed to improve portability and efficiency. Do not make 
* changes to this file unless you know what you are doing--modify the SWIG 
* interface file instead. 
* ----------------------------------------------------------------------------- */ 

#define SWIGJAVA 

/* ----------------------------------------------------------------------------- 
* This section contains generic SWIG labels for method/variable 
* declarations/attributes, and other compiler dependent labels. 
* ----------------------------------------------------------------------------- */ 

/* template workaround for compilers that cannot correctly implement the C++ standard */ 
#ifndef SWIGTEMPLATEDISAMBIGUATOR 
# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) 
# define SWIGTEMPLATEDISAMBIGUATOR template 
# elif defined(__HP_aCC) 
/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ 
/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ 
# define SWIGTEMPLATEDISAMBIGUATOR template 
# else 
# define SWIGTEMPLATEDISAMBIGUATOR 
# endif 
#endif 

/* inline attribute */ 
#ifndef SWIGINLINE 
# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) 
# define SWIGINLINE inline 
# else 
# define SWIGINLINE 
# endif 
#endif 

/* attribute recognised by some compilers to avoid 'unused' warnings */ 
#ifndef SWIGUNUSED 
# if defined(__GNUC__) 
# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 
#  define SWIGUNUSED __attribute__ ((__unused__)) 
# else 
#  define SWIGUNUSED 
# endif 
# elif defined(__ICC) 
# define SWIGUNUSED __attribute__ ((__unused__)) 
# else 
# define SWIGUNUSED 
# endif 
#endif 

#ifndef SWIG_MSC_UNSUPPRESS_4505 
# if defined(_MSC_VER) 
# pragma warning(disable : 4505) /* unreferenced local function has been removed */ 
# endif 
#endif 

#ifndef SWIGUNUSEDPARM 
# ifdef __cplusplus 
# define SWIGUNUSEDPARM(p) 
# else 
# define SWIGUNUSEDPARM(p) p SWIGUNUSED 
# endif 
#endif 

/* internal SWIG method */ 
#ifndef SWIGINTERN 
# define SWIGINTERN static SWIGUNUSED 
#endif 

/* internal inline SWIG method */ 
#ifndef SWIGINTERNINLINE 
# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE 
#endif 

/* exporting methods */ 
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 
# ifndef GCC_HASCLASSVISIBILITY 
# define GCC_HASCLASSVISIBILITY 
# endif 
#endif 

#ifndef SWIGEXPORT 
# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 
# if defined(STATIC_LINKED) 
#  define SWIGEXPORT 
# else 
#  define SWIGEXPORT __declspec(dllexport) 
# endif 
# else 
# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) 
#  define SWIGEXPORT __attribute__ ((visibility("default"))) 
# else 
#  define SWIGEXPORT 
# endif 
# endif 
#endif 

/* calling conventions for Windows */ 
#ifndef SWIGSTDCALL 
# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 
# define SWIGSTDCALL __stdcall 
# else 
# define SWIGSTDCALL 
# endif 
#endif 

/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) 
# define _CRT_SECURE_NO_DEPRECATE 
#endif 

/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ 
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) 
# define _SCL_SECURE_NO_DEPRECATE 
#endif 



/* Fix for jlong on some versions of gcc on Windows */ 
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) 
    typedef long long __int64; 
#endif 

/* Fix for jlong on 64-bit x86 Solaris */ 
#if defined(__x86_64) 
# ifdef _LP64 
# undef _LP64 
# endif 
#endif 

#include <jni.h> 
#include <stdlib.h> 
#include <string.h> 


/* Support for throwing Java exceptions */ 
typedef enum { 
    SWIG_JavaOutOfMemoryError = 1, 
    SWIG_JavaIOException, 
    SWIG_JavaRuntimeException, 
    SWIG_JavaIndexOutOfBoundsException, 
    SWIG_JavaArithmeticException, 
    SWIG_JavaIllegalArgumentException, 
    SWIG_JavaNullPointerException, 
    SWIG_JavaDirectorPureVirtual, 
    SWIG_JavaUnknownError 
} SWIG_JavaExceptionCodes; 

typedef struct { 
    SWIG_JavaExceptionCodes code; 
    const char *java_exception; 
} SWIG_JavaExceptions_t; 


static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { 
    jclass excep; 
    static const SWIG_JavaExceptions_t java_exceptions[] = { 
    { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, 
    { SWIG_JavaIOException, "java/io/IOException" }, 
    { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, 
    { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, 
    { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, 
    { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, 
    { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, 
    { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, 
    { SWIG_JavaUnknownError, "java/lang/UnknownError" }, 
    { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } 
    }; 
    const SWIG_JavaExceptions_t *except_ptr = java_exceptions; 

    while (except_ptr->code != code && except_ptr->code) 
    except_ptr++; 

    (*jenv)->ExceptionClear(jenv); 
    excep = (*jenv)->FindClass(jenv, except_ptr->java_exception); 
    if (excep) 
    (*jenv)->ThrowNew(jenv, excep, msg); 
} 


/* Contract support */ 

#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else 


#include "pjsua.h" 


#ifdef __cplusplus 
extern "C" { 
#endif 

#ifdef __cplusplus 
} 
#endif 

我有相同的位置,裏面的pjsua.h文件作爲我的.i文件所以它更容易找到兩者同時執行痛飲命令和任何意見?

我基本上想要swig或任何其他工具來創建一個pjsua或pjsip java類,它具有我可以用來實際使用庫的所有實現或接口方法。

如疼痛,有這個SIP協議棧

+1

JNI是明顯的選擇,或可能[JNA](https://github.com/twall/jna)。 – millimoose 2013-05-13 16:17:48

+0

仍然存在問題。它不會生成帶有C源代碼中所有函數的jni。我甚至試圖複製和從C源代碼到所有我的jNI東西與標題以及 – jonney 2013-05-21 10:58:35

回答

3

嘗試JNA與JNAerator:https://code.google.com/p/jnaerator。我已經在自己的項目中成功地使用了它。

+0

這個技巧的有效參數。是非常fiddly得到它的工作,但最終做 – jonney 2013-05-28 08:32:45

+0

@jonney你能提供你的JNA類/接口?也許一個Github鏈接? – Chriss 2015-11-28 19:36:27

3

沒有java版我發現做到這一點最簡單的方法,如果你的頭文件,就是用SWIG。您爲您的模塊(庫)創建一個yourmodule.i文件,幷包含您想要通過JNI訪問的所有類。例如:

%module Foo 
%{ 
#include "Bar.h" 
%} 

您還可以提供從C到Java結構的類型映射。

如果你想忽略特定方法:

%ignore fooBar(int baz); 

您可以運行痛飲產生一些像這樣的Java類:

swig -c -verbose -java -package com.your.java.package -o jni_wrapper.c yourfile.i 

的更多信息和示例見Java documentation

+0

嗨。這看起來很有趣,所以我所做的就是創建一個.i文件並添加類似的代碼片段,以說Java類Foo將代表Bar.H的函數或頭文件,並且通過使用SWIG,我可以自動生成可以訪問的Foo類來自Bar.h的所有代碼? – jonney 2013-05-14 08:40:14

+0

您好,我遵循上面的建議步驟,它所做的只是產生一個沒有在JNI上定義的方法的空類。有什麼建議? – jonney 2013-05-14 14:39:28

+0

您是否閱讀過文檔?那裏有很多例子。您可能需要手動將頭文件包含在'.i'文件中。 – 2013-05-14 19:03:50

2

我會建議使用Javacpp我之前用它和它的工作還不錯,你在這裏需要的東西只是一個橋樑,SWIG是不是很友好,而且我以前浪費了很多的時間與它。

至於請求的特定庫,試試這個pjsip-jni,它是用java和jni編寫的pjsip的包裝器。

+0

Javacpp很好用,最好是包裝C++代碼,+1 – anshulkatta 2013-05-28 06:22:54

+0

儘管javacpp在較低級別使用jni – anshulkatta 2013-05-28 06:24:00