2013-05-13 25 views
8

Có cách nào để sử dụng và gọi các cuộc gọi phương thức từ một thư viện được biên dịch trong C chẳng hạn như thư viện PJSIP không?Cách sử dụng thư viện C như PJSIP trên java?

Tôi muốn sử dụng và gọi các cuộc gọi từ lib pjsip mà tôi đã biên soạn nhưng vấn đề rõ ràng là pjsip là thư viện C không phải là thư viện java tức là tệp jar.

Có thể? Có lẽ JNI?

Cảm ơn

chỉnh sửa: cố gắng sử dụng Uống một lân để làm nhiệm vụ trong tầm tay nhưng tất cả nó làm là tạo ra một tập tin lớp trống.

đây là lệnh tôi sử dụng để thực hiện uống một lân:

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

đầu ra từ lệnh uống một lân

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 lớp nó tạo cho tô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 { 
} 

Các pjsua JNI tệp tạo cho tô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 pjsuaJNI { 
} 

Các jni_wrapper.c nó tạo cho tôi dưới đây:

/* ---------------------------------------------------------------------------- 
* 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 

Tôi có tập tin pjsua.h bên trong cùng một vị trí với file .i của tôi vì vậy nó dễ dàng hơn để tìm thấy cả hai trong khi thực hiện lệnh uống một lân và lời khuyên nào ?

Tôi về cơ bản muốn swig hoặc bất kỳ công cụ nào khác để tạo lớp java pjsua hoặc pjsip với tất cả các triển khai hoặc phương thức giao diện mà tôi có thể sử dụng để thực sự sử dụng thư viện.

Chẳng hạn như một nỗi đau mà không có phiên bản java của ngụm này chồng

+1

JNI là lựa chọn hiển nhiên hoặc có thể [JNA] (https://github.com/twall/jna). – millimoose

+0

vẫn gặp sự cố. nó đơn giản sẽ không tạo ra jni với tất cả các hàm được tìm thấy trong mã nguồn C. tôi thậm chí đã cố gắng để sao chép và qua mã nguồn từ C vào cùng một vị trí như tất cả các công cụ jNI của tôi với các tiêu đề cũng như – jonney

Trả lời

3

Hãy thử JNA với JNAerator: https://code.google.com/p/jnaerator. Tôi đã sử dụng nó thành công trong các dự án của riêng tôi.

+0

điều này đã làm các trick. đã khá khó khăn để làm cho nó hoạt động nhưng cuối cùng đã làm – jonney

+0

@jonney bạn có thể cung cấp các lớp/giao diện JNA của bạn không? Có lẽ một liên kết github? – Chriss

3

tôi đã tìm thấy cách đơn giản nhất để làm điều này, nếu bạn có các tập tin tiêu đề, là sử dụng SWIG. Bạn tạo một tệp yourmodule.i cho mô-đun của mình (thư viện) và bao gồm tất cả các lớp bạn muốn truy cập qua JNI. Ví dụ:

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

Bạn cũng có thể cung cấp bản đồ từ C đến cấu trúc Java.

Nếu bạn muốn bỏ qua một phương pháp nhất định:

%ignore fooBar(int baz); 

Bạn có thể chạy uống một lân để tạo ra một số các lớp học java như thế này:

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

Xem Java documentation để biết thêm thông tin và ví dụ.

+0

Xin chào. Điều này có vẻ thú vị vì vậy tất cả những gì tôi làm là tạo một tệp .i và thêm đoạn mã tương tự để nói rằng một lớp java Foo sẽ đại diện cho hàm hoặc tệp tiêu đề của Bar.H và bằng cách sử dụng SWIG tôi có thể tự động tạo Lớp Foo. cho tất cả các mã từ Bar.h? – jonney

+0

Xin chào i đã làm theo các bước gợi ý ở trên và tất cả những gì đã làm là tạo ra một lớp trống không có phương thức nào được định nghĩa trên JNI. lời khuyên nào? – jonney

+0

Bạn đã đọc tài liệu chưa? Có rất nhiều ví dụ ở đó. Bạn có thể cần phải tự bao gồm các tệp tiêu đề bên trong tệp '.i'. –

2

Tôi khuyên bạn nên sử dụng Javacpp Tôi đã sử dụng nó trước đây và nó hoạt động khá tốt, thứ bạn cần ở đây chỉ là một cây cầu, SWIG không thân thiện lắm và tôi lãng phí rất nhiều thời gian với nó trước đây.

Đối với thư viện cụ thể được yêu cầu, hãy thử cái này pjsip-jni, trình bao bọc của nó cho pjsip được viết bằng java và jni.

+0

Javacpp hoạt động tốt, tốt nhất là gói mã C++, +1 – anshulkatta

+0

mặc dù javacpp sử dụng jni ở các cấp thấp hơn – anshulkatta