2013-05-13 13 views
8

C'è un modo per utilizzare e richiamare chiamate di metodo da una libreria compilata in C come la libreria PJSIP?Come utilizzare una libreria C come PJSIP su java?

Desidero utilizzare e invocare chiamate dalla lib di pjsip che ho compilato ma il problema ovvio è che pjsip è una libreria C non una libreria java, ad esempio un file jar.

Possibile? Forse JNI?

Grazie

EDIT: provato ad utilizzare Swig di fare il compito a portata di mano, ma tutto quello che fa è creare un file di classe vuota.

qui è il comando che uso per eseguire sorso:

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

uscita dal comando sorso

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 classe Java che crea per me:

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

La JNI pjsua file creato per me

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

Il jni_wrapper.c che genera per me di seguito:

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

ho il file pjsua.h all'interno stesso percorso mio file .i così è più facile trovare sia, mentre l'esecuzione del comando sorso e qualche consiglio ?

Fondamentalmente voglio swig o qualsiasi altro strumento per creare una classe java pjsua o pjsip con tutte le sue implementazioni o metodi di interfaccia che posso usare per utilizzare effettivamente la libreria.

Come ad esempio un dolore che non esiste una versione Java di questo sorso pila

+1

JNI è la scelta più ovvia, o forse [JNA] (https://github.com/twall/jna). – millimoose

+0

continuano ad avere problemi. semplicemente non genererà il jni con tutte le funzioni trovate nel codice sorgente C. Ho anche provato a copiare e incollare il codice sorgente da C nella stessa posizione di tutte le mie cose JNI con le intestazioni pure – jonney

risposta

3

Provare JNA con JNAerator: https://code.google.com/p/jnaerator. L'ho usato con successo nei miei progetti.

+0

questo ha fatto il trucco. è stato abbastanza laborioso per farlo funzionare, ma alla fine lo ha fatto – jonney

+0

@ jonney puoi fornire le tue classi/interfacce JNA? Forse un link Github? – Chriss

3

ho trovato il modo più semplice per fare questo, se avete i file di intestazione, è quello di utilizzare SWIG. Si crea un file yourmodule.i per il modulo (la libreria) e si includono tutte le classi a cui si desidera accedere tramite JNI. E.g:

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

È inoltre possibile fornire typemaps da strutture C a Java.

Se si desidera ignorare un certo metodo:

%ignore fooBar(int baz); 

È possibile eseguire sorso di generare alcune classi Java in questo modo:

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

Vedere la Java documentation per ulteriori informazioni ed esempi.

+0

Ciao. Questo sembra interessante quindi tutto ciò che faccio è creare un file .i e aggiungere uno snippet di codice simile per dire che una classe java Foo rappresenterà la funzione o il file di intestazione di Bar.H e usando SWIG posso generare automaticamente Class Foo che avrà accesso a tutto il codice da Bar.h? – jonney

+0

Ciao ho seguito la procedura di suggerimento sopra e tutto ciò che è stato fatto è stato produrre una classe vuota senza metodi definiti sul JNI. qualche consiglio? – jonney

+0

Hai letto la documentazione? Ci sono molti esempi lì. Potrebbe essere necessario includere manualmente i file di intestazione all'interno del file '.i'. –

2

Si consiglia di utilizzare Javacpp L'ho usato prima e ha funzionato abbastanza bene, la cosa di cui avete bisogno qui è solo un ponte, SWIG non è molto amichevole, e ho sprecato un sacco di tempo con esso prima.

Come per la libreria specifica richiesta, provare questo pjsip-jni, il suo wrapper per il pjsip scritto in java e jni.

+0

Javacpp funziona alla grande, è meglio per il wrapping del codice C++, +1 – anshulkatta

+0

sebbene javacpp usi jni nei livelli più bassi – anshulkatta