- Timestamp:
- Jul 11, 2013 5:35:05 AM (11 years ago)
- Location:
- pjproject/branches/projects/jni
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/jni/pjsip-apps/src/jni/Makefile
r4549 r4557 21 21 MY_OUT_DIR = output 22 22 MY_SWIG_IF = $(MY_OUT_DIR)/pjsua.i 23 MY_SWIG_FLAG = -c++ -I$(MY_OUT_DIR) # - Wall23 MY_SWIG_FLAG = -c++ -I$(MY_OUT_DIR) # -debug-tmsearch -debug-tmused # -Wall 24 24 MY_SWIG_WRAPPER = $(MY_OUT_DIR)/pjsua_wrap 25 25 MY_PACKAGE_SRC = $(MY_OUT_DIR)/src/$(subst .,/,$(MY_PACKAGE)) -
pjproject/branches/projects/jni/pjsip-apps/src/jni/callbacks.i
r4549 r4557 6 6 7 7 %feature("director") PjsuaCallback; 8 %ignore pjsua_callback; 8 9 %ignore pjsua_config::cb; 9 10 %extend pjsua_config { -
pjproject/branches/projects/jni/pjsip-apps/src/jni/header.i
r4549 r4557 16 16 17 17 /* Map 'void *' simply as long, app can use this "long" as index of its real user data */ 18 %apply long { void * };18 %apply long long { void * }; 19 19 20 20 /* Handle void *[ANY], e.g: pjsip_tx_data::mod_data, pjsip_transaction::mod_data */ 21 21 //%ignore pjsip_tx_data::mod_data; 22 22 //%ignore pjsip_transaction::mod_data; 23 %apply long [ANY]{ void *[ANY] };23 %apply long long[ANY] { void *[ANY] }; 24 24 25 25 /* Map "int*" & "unsigned*" as input & output */ 26 26 %apply unsigned *INOUT { unsigned * }; 27 %apply int 27 %apply int *INOUT { int * }; 28 28 29 29 /* Map the following args as input & output */ 30 %apply int *INOUT { pj_stun_nat_type * }; 31 %apply int *INOUT { pjsip_status_code * }; 32 %apply int[ANY] { pjmedia_format_id dec_fmt_id[ANY] }; 30 %apply int *INOUT { pj_stun_nat_type * }; 31 %apply int *INOUT { pjsip_status_code * }; 32 %apply int[ANY] { pjmedia_format_id dec_fmt_id[ANY] }; 33 %apply pj_str_t *INOUT { pj_str_t *p_contact }; 33 34 34 /* Handle array of pj_str_t */ 35 JAVA_ARRAYSOFCLASSES(pj_str_t) 35 /* Handle members typed array of pj_str_t */ 36 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_config, nameserver, nameserver_count) 37 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_config, outbound_proxy, outbound_proxy_cnt) 38 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_config, stun_srv, stun_srv_cnt) 39 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_acc_config, proxy, proxy_cnt) 40 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_config, stun_srv, stun_srv_cnt) 41 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsua_config, stun_srv, stun_srv_cnt) 42 MY_JAVA_MEMBER_ARRAY_OF_STR(pjsip_generic_array_hdr, values, count) 36 43 37 44 /* Handle pointer-to-pointer-to-object as input & output */ -
pjproject/branches/projects/jni/pjsip-apps/src/jni/hello.java
r4549 r4557 4 4 import java.io.InputStreamReader; 5 5 import java.io.IOException; 6 7 import org.pjsip.pjsua.pj_pool_t; 8 import org.pjsip.pjsua.pjsip_rx_data; 9 import org.pjsip.pjsua.pjsip_transport_type_e; 10 6 11 import org.pjsip.pjsua.pjsua; 7 12 import org.pjsip.pjsua.pjsua_acc_config; … … 11 16 import org.pjsip.pjsua.pjsua_logging_config; 12 17 import org.pjsip.pjsua.pjsua_transport_config; 13 import org.pjsip.pjsua.pjsip_transport_type_e;14 import org.pjsip.pjsua.pj_str_t;15 18 import org.pjsip.pjsua.PjsuaCallback; 16 19 … … 19 22 public void on_call_media_state(int call_id) 20 23 { 21 System.out.println("======== Call media started (call id: " + call_id + ")"); 22 pjsua_call_info info = new pjsua_call_info(); 23 pjsua.call_get_info(call_id, info); 24 if (info.getMedia_status() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE) { 25 pjsua.conf_connect(info.getConf_slot(), 0); 26 pjsua.conf_connect(0, info.getConf_slot()); 27 } 24 System.out.println("======== Call media started (call id: " + call_id + ")"); 25 pjsua_call_info info = new pjsua_call_info(); 26 pjsua.call_get_info(call_id, info); 27 if (info.getMedia_status() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE) { 28 pjsua.conf_connect(info.getConf_slot(), 0); 29 pjsua.conf_connect(0, info.getConf_slot()); 30 } 31 } 32 @Override 33 public void on_pager(int call_id, String from, String to, String contact, String mime_type, String body) 34 { 35 System.out.println("======== Incoming pager (call id: " + call_id + ")"); 36 System.out.println("From : " + from); 37 System.out.println("To : " + to); 38 System.out.println("Contact : " + contact); 39 System.out.println("Mimetype : " + mime_type); 40 System.out.println("Body : " + body); 41 } 42 @Override 43 public void on_incoming_call(int acc_id, int call_id, pjsip_rx_data rdata) { 44 /* Auto answer */ 45 pjsua.call_answer(call_id, 200, null, null); 28 46 } 29 47 } … … 40 58 } 41 59 42 protected static pj_str_t pj_str(String st) {43 pj_str_t st_ = new pj_str_t();44 st_.setPtr(st);45 st_.setSlen(st.length());46 return st_;47 }48 49 60 public static void main(String[] args) { 50 61 int[] tp_id = new int[1]; … … 105 116 106 117 /* Make call to the URL. */ 107 { 108 pj_str_t call_target = pj_str("sip:localhost"); 109 status = pjsua.call_make_call(acc_id[0], call_target, null, 0, null, call_id); 118 if (false) { 119 status = pjsua.call_make_call(acc_id[0], "sip:localhost", null, 0, null, call_id); 110 120 if (status != pjsua.PJ_SUCCESS) { 111 121 pj_error_exit("Error making call", status); … … 117 127 String userInput; 118 128 BufferedReader inBuffReader = new BufferedReader(new InputStreamReader(System.in)); 129 130 System.out.println("Press 'h' to hangup all calls, 'q' to quit"); 131 119 132 try { 120 133 userInput = inBuffReader.readLine(); … … 124 137 } 125 138 126 System.out.println("Press 'h' to hangup all calls, 'q' to quit"); 127 128 if (userInput.equals("q")) 139 if (userInput.equals("q")) { 129 140 break; 130 131 if (userInput.equals("h")) 141 } else if (userInput.equals("h")) { 132 142 pjsua.call_hangup_all(); 143 } else if (userInput.equals("c")) { 144 /* Test string as output param, it is wrapped as string array */ 145 String[] contact = new String[1]; 146 pj_pool_t my_pool = pjsua.pool_create("hello", 256, 256); 147 148 pjsua.acc_create_uac_contact(my_pool, contact, 0, "sip:localhost"); 149 System.out.println("Test create contact: " + contact[0]); 150 151 pjsua.pj_pool_release(my_pool); 152 } 133 153 } 134 154 -
pjproject/branches/projects/jni/pjsip-apps/src/jni/my_typemaps.i
r4549 r4557 4 4 %include "typemaps.i" 5 5 6 /* Add director typemaps for "int *INOUT" */ 6 /* Auto destroy JNI object, useful for director */ 7 %inline %{ 8 class LocalRefGuard { 9 JNIEnv* jenv; 10 jobject jobj; 11 public: 12 LocalRefGuard(JNIEnv* jenv_, jobject jobj_) : jenv(jenv_), jobj(jobj_) {} 13 ~LocalRefGuard() { if (jobj) jenv->DeleteLocalRef(jobj); } 14 }; 15 %} 16 17 /* 18 * Add director typemaps for "int *INOUT" 19 */ 7 20 %typemap(javadirectorin) int *INOUT "$jniinput" 8 21 %typemap(directorin, descriptor="[I") int *INOUT %{ 9 22 $input = jenv->NewIntArray(1); 23 LocalRefGuard g_$input(jenv, $input); 10 24 jenv->SetIntArrayRegion($input, 0, 1, (jint*)$1); 11 25 %} 12 26 %typemap(directorout) int *INOUT %{ 13 jint * tmp$result = jenv->GetIntArrayElements($input, 0);14 *$result = tmp$result[0];15 jenv->ReleaseIntArrayElements($input, tmp$result, JNI_ABORT);27 jint tmp$result; 28 jenv->GetIntArrayRegion($input, 0, 1, &tmp$result); 29 *$result = ($*1_ltype)tmp$result; 16 30 %} 17 31 %typemap(directorargout) int *INOUT %{ 18 jint* tmp$1 = jenv->GetIntArrayElements($input, 0); 19 *$1 = ($*1_ltype) tmp$1[0]; 20 jenv->ReleaseIntArrayElements($input, tmp$1, JNI_ABORT); 21 %} 22 23 /* Add director typemaps for "unsigned *INOUT" */ 32 jint tmp$1; 33 jenv->GetIntArrayRegion($input, 0, 1, &tmp$1); 34 *$1 = ($*1_ltype)tmp$1; 35 %} 36 37 /* 38 * Add director typemaps for "unsigned *INOUT" 39 */ 24 40 %typemap(javadirectorin) unsigned *INOUT "$jniinput" 25 41 %typemap(directorin, descriptor="[I") unsigned *INOUT %{ 26 42 $input = jenv->NewLongArray(1); 43 LocalRefGuard g_$input(jenv, $input); 27 44 jenv->SetLongArrayRegion($input, 0, 1, (jlong*)$1); 28 45 %} 29 46 %typemap(directorout) unsigned *INOUT %{ 30 jlong * tmp$result = jenv->GetLongArrayElements($input, 0);31 *$result = tmp$result[0];32 jenv->ReleaseLongArrayElements($input, tmp$result, JNI_ABORT);47 jlong tmp$result; 48 jenv->GetLongArrayRegion($input, 0, 1, &tmp$result); 49 *$result = ($*1_ltype)tmp$result; 33 50 %} 34 51 %typemap(directorargout) unsigned *INOUT %{ 35 jlong* tmp$1 = jenv->GetLongArrayElements($input, 0); 36 *$1 = ($*1_ltype) tmp$1[0]; 37 jenv->ReleaseLongArrayElements($input, tmp$1, JNI_ABORT); 38 %} 52 jlong tmp$1; 53 jenv->GetLongArrayRegion($input, 0, 1, &tmp$1); 54 *$1 = ($*1_ltype)tmp$1; 55 %} 56 57 /* 58 * Map pj_str_t to java String 59 */ 60 %ignore pj_str_t; 61 %typemap(jni) pj_str_t* "jstring" 62 %typemap(jtype) pj_str_t* "String" 63 %typemap(jstype) pj_str_t* "String" 64 %typemap(javain) pj_str_t* "$javainput" 65 %typemap(javaout) pj_str_t* { return $jnicall; } 66 %typemap(javadirectorin) pj_str_t* "$jniinput" 67 %typemap(javadirectorout) pj_str_t* "$javacall" 68 69 %typemap(in) pj_str_t* (pj_str_t str_tmp, char* str_ptr=NULL) %{ 70 $1 = &str_tmp; 71 if(!$input) pj_strset($1, NULL, 0); 72 else { 73 str_ptr = (char*)jenv->GetStringUTFChars($input, 0); 74 pj_size_t str_len = jenv->GetStringUTFLength($input); 75 if (!str_ptr || !str_len) pj_strset($1, NULL, 0); 76 else pj_strset($1, str_ptr, str_len); 77 } 78 %} 79 80 %typemap(freearg) pj_str_t* %{ 81 if ($input) 82 jenv->ReleaseStringUTFChars($input, str_ptr$argnum); 83 %} 84 85 %typemap(memberin) pj_str_t %{ 86 if ($1.ptr) free($1.ptr); 87 if ($input->ptr) { 88 $1.ptr = (char*)malloc($input->slen); /* <-- will leak! */ 89 memcpy($1.ptr, $input->ptr, $input->slen); 90 $1.slen = $input->slen; 91 } 92 %} 93 94 %typemap(out) pj_str_t* %{ 95 char *$1_ptr = (char*)malloc($1->slen+1); 96 memcpy($1_ptr, $1->ptr, $1->slen); 97 $1_ptr[$1->slen] = '\0'; 98 $result = jenv->NewStringUTF($1_ptr); 99 free($1_ptr); 100 %} 101 102 %typemap(directorin,descriptor="Ljava/lang/String;") pj_str_t* %{ 103 char *$input_ptr = (char*)malloc($1->slen+1); 104 memcpy($input_ptr, $1->ptr, $1->slen); 105 $input_ptr[$1->slen] = '\0'; 106 $input = jenv->NewStringUTF($input_ptr); 107 LocalRefGuard g_$input(jenv, $input); 108 free($input_ptr); 109 %} 110 111 /* 112 * Map pj_str_t[ANY] to java String[] 113 */ 114 %typemap(jni) pj_str_t[ANY] "jobjectArray" 115 %typemap(jtype) pj_str_t[ANY] "String[]" 116 %typemap(jstype) pj_str_t[ANY] "String[]" 117 %typemap(javain) pj_str_t[ANY] "$javainput" 118 %typemap(javaout) pj_str_t[ANY] { return $jnicall; } 119 %typemap(in) pj_str_t[ANY] %{ 120 int $1_len = jenv->GetArrayLength($input); 121 char** $1_tmpstr = new char*[$1_len]; 122 jstring* $1_tmp = new jstring[$1_len]; 123 $1 = new pj_str_t[$1_len]; 124 int $1_ii; 125 for ($1_ii = 0; $1_ii<$1_len; $1_ii++) { 126 $1_tmp[$1_ii] = (jstring)jenv->GetObjectArrayElement($input, $1_ii); 127 if ($1_tmp[$1_ii]) { 128 $1[$1_ii].ptr = $1_tmpstr[$1_ii] = (char*)jenv->GetStringUTFChars($1_tmp[$1_ii], 0); 129 $1[$1_ii].slen = jenv->GetStringUTFLength($1_tmp[$1_ii]); 130 } else { 131 pj_strset(&$1[$1_ii], NULL, 0); 132 } 133 jenv->DeleteLocalRef($1_tmp[$1_ii]); /* is this ok here? */ 134 } 135 %} 136 137 %typemap(freearg) pj_str_t[ANY] %{ 138 for ($1_ii=0; $1_ii<$1_len; $1_ii++) 139 if ($1_tmp[$1_ii]) jenv->ReleaseStringUTFChars($1_tmp[$1_ii], $1_tmpstr[$1_ii]); 140 delete [] $1; 141 delete [] $1_tmp; 142 delete [] $1_tmpstr; 143 %} 144 145 /* 146 * Handle setter/getter of a struct member with type of 'array of pj_str_t'. 147 */ 148 %define MY_JAVA_MEMBER_ARRAY_OF_STR(CLASS_NAME, NAME, COUNT_NAME) 149 150 %ignore CLASS_NAME::COUNT_NAME; 151 152 %typemap(memberin) pj_str_t NAME[ANY], pj_str_t NAME[] { 153 int i; 154 for (i=0; i<arg1->COUNT_NAME; ++i) 155 if ($1[i].ptr) free($1[i].ptr); 156 157 arg1->COUNT_NAME = $input_len; 158 for (i=0; i<arg1->COUNT_NAME; ++i) { 159 if ($input->ptr) { 160 $1[i].ptr = (char*)malloc($input->slen); /* <-- will leak! */ 161 memcpy($1[i].ptr, $input->ptr, $input->slen); 162 $1[i].slen = $input->slen; 163 } 164 } 165 } 166 167 %typemap(out) pj_str_t NAME[ANY] { 168 int i; 169 jstring temp_string; 170 const jclass clazz = jenv->FindClass("java/lang/String"); 171 172 $result = jenv->NewObjectArray(arg1->COUNT_NAME, clazz, NULL); 173 for (i=0; i<arg1->COUNT_NAME; i++) { 174 temp_string = jenv->NewStringUTF($1[i].ptr); 175 jenv->SetObjectArrayElement($result, i, temp_string); 176 jenv->DeleteLocalRef(temp_string); 177 } 178 } 179 180 %enddef 181 182 /* 183 * pj_str_t *INOUT, string as input and output param, handled as single element array. 184 */ 185 %apply pj_str_t[ANY] { pj_str_t *INOUT }; 186 187 %typemap(argout) pj_str_t *INOUT { 188 char *$1_ptr = new char[$1[0].slen+1]; 189 memcpy($1_ptr, $1[0].ptr, $1[0].slen); 190 $1_ptr[$1[0].slen] = '\0'; 191 jstring temp_string = jenv->NewStringUTF($1_ptr); 192 jenv->SetObjectArrayElement($input, 0, temp_string); 193 delete [] $1_ptr; 194 } 195 196 %typemap(directorin,descriptor="[Ljava/lang/String;") pj_str_t *INOUT %{ 197 jstring tmp_$input; 198 $input = jenv->NewObjectArray(1, jenv->FindClass("java/lang/String"), NULL); 199 LocalRefGuard g_$input(jenv, $input); 200 tmp_$input = jenv->NewStringUTF($1[0].ptr); 201 LocalRefGuard g_temp_$input(jenv, tmp_$input); 202 jenv->SetObjectArrayElement($input, 0, tmp_$input); 203 %} 204 205 %typemap(directorargout) pj_str_t *INOUT { 206 if(!$input) pj_strset($1, NULL, 0); 207 else { 208 str_ptr = (char*)jenv->GetStringUTFChars($input, 0); 209 pj_size_t str_len = jenv->GetStringUTFLength($input); 210 if (!str_ptr || !str_len) pj_strset($1, NULL, 0); 211 else { 212 $1->ptr = (char*)malloc(str_len); /* <-- will leak! */ 213 memcpy($1->ptr, str_ptr, str_len); 214 $1->slen = str_len; 215 } 216 } 217 } 218 39 219 40 220 /* … … 45 225 %typemap(jtype) TYPE **NAME "long" 46 226 %typemap(jstype) TYPE **NAME "TYPE" 47 %typemap(in) TYPE **NAME (TYPE *temp = NULL) { temp = (TYPE*)$input; $1 = &temp; }48 %typemap(argout) TYPE **NAME "$input = (jlong)*$1;" 227 %typemap(in) TYPE **NAME (TYPE *temp = NULL) "temp = (TYPE*)$input; $1 = &temp;" 228 %typemap(argout) TYPE **NAME "$input = (jlong)*$1;" 49 229 %typemap(directorin,descriptor="L$packagepath/TYPE;") TYPE **NAME "$input = (jlong)*$1;" 50 %typemap(directorargout) TYPE **NAME " *$1 = (TYPE*)$input; "51 %typemap(javain) TYPE **NAME "TYPE.getCPtr($javainput)"52 %typemap(javadirectorin) TYPE **NAME "($jniinput == 0) ? null : new TYPE($jniinput, false)"230 %typemap(directorargout) TYPE **NAME " *$1 = (TYPE*)$input; " 231 %typemap(javain) TYPE **NAME "TYPE.getCPtr($javainput)" 232 %typemap(javadirectorin) TYPE **NAME "($jniinput == 0) ? null : new TYPE($jniinput, false)" 53 233 %typemap(javadirectorout) TYPE **NAME "TYPE.getCPtr($javacall)" 54 234 %enddef … … 57 237 /* 58 238 * Generate setter/getter of a struct member typed of 'array of enum' with variable length. 59 * Sample usage, given enum array member in this struct:60 * --61 * struct pjsip_tls_setting {62 * ..63 * unsigned ciphers_num;64 * pj_ssl_cipher *ciphers;65 * ..66 * };67 * --68 * apply:69 * MY_JAVA_MEMBER_ARRAY_OF_ENUM(pjsip_tls_setting, pj_ssl_cipher, ciphers, ciphers_num)70 239 */ 71 240 %define MY_JAVA_MEMBER_ARRAY_OF_ENUM(CLASS_NAME, TYPE, NAME, COUNT_NAME) 72 241 73 %apply ARRAYSOFENUMS[] { TYPE* };74 %typemap(out) TYPE* %{ $result = SWIG_JavaArrayOutInt(jenv, (int*)$1, arg1->COUNT_NAME); %}75 %ignore CLASS_NAME::NAME;76 242 %ignore CLASS_NAME::COUNT_NAME; 77 %extend CLASS_NAME { 78 %rename ("%(lowercamelcase)s") set_##NAME; 79 %rename ("%(lowercamelcase)s") get_##NAME; 80 void set_##NAME(TYPE *NAME, int num) { 81 int i; 82 if ($self->NAME) free($self->NAME); 83 $self->NAME = (TYPE*)calloc(num, sizeof(TYPE)); 84 for (i=0; i<num; ++i) $self->NAME[i] = NAME[i]; 85 $self->COUNT_NAME = num; 86 } 87 TYPE* get_##NAME() { 88 return $self->NAME; 89 } 90 ~CLASS_NAME() { 91 if ($self->NAME) free($self->NAME); 92 } 93 }; 243 %apply ARRAYSOFENUMS[] { TYPE* NAME }; 244 245 %typemap(in) TYPE* NAME (jint *jarr) %{ 246 int size$1 = jenv->GetArrayLength($input); 247 if (!SWIG_JavaArrayInInt(jenv, &jarr, (int **)&$1, $input)) return $null; 248 %} 249 250 %typemap(memberin) TYPE* NAME %{ 251 if ($1) free($1); 252 arg1->COUNT_NAME = size$input; 253 $1 = (TYPE*)calloc(arg1->COUNT_NAME, sizeof(TYPE)); /* <-- will leak! */ 254 for (size_t i = 0; i < (size_t)arg1->COUNT_NAME; i++) 255 $1[i] = $input[i]; 256 %} 257 258 %typemap(out) TYPE* NAME %{ 259 $result = SWIG_JavaArrayOutInt(jenv, (int*)$1, arg1->COUNT_NAME); 260 %} 261 262 // Hack for avoiding leak, may not work when another macro defines class destructor too 263 %extend CLASS_NAME { ~CLASS_NAME() { if ($self->NAME) free($self->NAME); } }; 94 264 95 265 %enddef … … 97 267 98 268 /* 99 * Handle getter of a struct member with type of 'array of pointer to struct/class'. 100 * Currently this is applicable for read-only member. 269 * Handle setter/getter of a struct member with type of 'array of pointer to struct/class'. 101 270 */ 102 271 %define MY_JAVA_MEMBER_ARRAY_OF_POINTER(CLASS_NAME, TYPE, NAME, COUNT_NAME) 103 272 104 273 %ignore CLASS_NAME::COUNT_NAME; 105 %immutable CLASS_NAME::NAME; 106 %typemap(jni) TYPE *[ANY] "jlongArray" 107 %typemap(jtype) TYPE *[ANY] "long[]" 108 %typemap(jstype) TYPE *[ANY] "TYPE[]" 109 %typemap(javain) TYPE *[ANY] "TYPE.cArrayUnwrap($javainput)" 110 %typemap(javaout) TYPE *[ANY] {return TYPE.cArrayWrap($jnicall, $owner);} 111 112 // somehow "$result" is not preprocessed in "typemap(ret)", use 'jresult' directly then 113 %typemap(ret) TYPE *[ANY] { 114 jlong *arr; 115 int i; 116 jresult = JCALL1(NewLongArray, jenv, arg1->COUNT_NAME); 117 if (!jresult) { 274 %typemap(jni) TYPE* NAME[ANY] "jlongArray" 275 %typemap(jtype) TYPE* NAME[ANY] "long[]" 276 %typemap(jstype) TYPE* NAME[ANY] "TYPE[]" 277 %typemap(javain) TYPE* NAME[ANY] "TYPE.cArrayUnwrap($javainput)" 278 %typemap(javaout) TYPE* NAME[ANY] {return TYPE.cArrayWrap($jnicall, $owner);} 279 280 %typemap(in) TYPE* NAME[ANY] (jlong *jarr) %{ 281 if (!SWIG_JavaArrayInUlong(jenv, &jarr, (unsigned long**)&$1, $input)) 118 282 return $null; 119 } 120 arr = JCALL2(GetLongArrayElements, jenv, jresult, 0); 121 if (!arr) { 122 return $null; 123 } 124 for (i=0; i<arg1->COUNT_NAME; i++) { 125 arr[i] = 0; 126 *($1_ltype)&arr[i] = $1[i]; 127 } 128 JCALL3(ReleaseLongArrayElements, jenv, jresult, arr, 0); 129 } 283 arg1->COUNT_NAME = jenv->GetArrayLength($input); 284 %} 285 286 %typemap(freearg) TYPE* NAME[ANY] %{ if ($1) delete [] $1; %} 287 288 %typemap(memberin) TYPE* NAME[ANY] %{ 289 for (size_t i = 0; i < (size_t)arg1->COUNT_NAME; i++) $1[i] = $input[i]; 290 %} 291 292 %typemap(out) TYPE* NAME[ANY] %{ 293 $result = SWIG_JavaArrayOutUlong(jenv, (unsigned long*)$1, arg1->COUNT_NAME); 294 %} 130 295 131 296 %typemap(javacode) TYPE %{ 132 297 protected static long[] cArrayUnwrap($javaclassname[] arrayWrapper) { 133 134 135 136 298 long[] cArray = new long[arrayWrapper.length]; 299 for (int i=0; i<arrayWrapper.length; i++) 300 cArray[i] = $javaclassname.getCPtr(arrayWrapper[i]); 301 return cArray; 137 302 } 138 303 protected static $javaclassname[] cArrayWrap(long[] cArray, boolean cMemoryOwn) { -
pjproject/branches/projects/jni/pjsip-apps/src/jni/swig_gen.py
r4549 r4557 15 15 16 16 # CPP (C preprocessor) settings, CPP is needed by pycparser. 17 CPP_PATH 17 CPP_PATH = 'C:/devs/bin/cpp.exe' if sys.platform == 'win32' else 'cpp' 18 18 CPP_CFLAGS = [ 19 19 r'-DPJ_AUTOCONF', … … 56 56 'pjmedia_port', 57 57 'pjmedia_transport', 58 'pjsua_media_transport', 59 'pjsua_callback', 60 'pjmedia_stream' 58 'pjsua_media_transport' 61 59 ] 62 60 63 61 FORCE_EXPORT = [ 64 'pjsip_event', 65 'pjsip_transaction', 66 'pjmedia_sdp_session', 67 #'pj_str' # plain export result doesn't work! 62 'pj_pool_release' 68 63 ] 69 64 70 65 class MyGen(c_generator.CGenerator): 71 72 73 74 75 76 self.deps = list()77 self.deps_pending = list()78 self.deps_frozen = False79 80 # Generate nodes map (name -> node instances)81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 self.deps_frozen = True101 102 103 104 105 if not self.deps_frozen:106 107 return super(MyGen, self).visit_IdentifierType(n)108 109 110 if NO_VIDEO and name and ((name.find('_vid_') > 0) or (name.find('_video_') > 0)):111 112 return True113 114 115 116 if s:117 118 if isinstance(node, c_ast.FuncDef):119 120 ss = getattr(node, 'names', None)121 if ss:122 123 124 if getattr(node, 'type', None):125 126 return s127 128 129 130 131 132 133 134 135 if name in FORCE_STRUCT_AS_OPAQUE and (not name == 'pjsua_callback'):136 137 138 139 self.deps_pending.append(name)140 for node in self.nodes[name]:141 142 if not self.deps_pending.pop() == name:143 144 145 self.deps.append(name)146 147 148 149 if isinstance(node, c_ast.Typedef) and isinstance(node.type, c_ast.TypeDecl) and \150 isinstance(node.type.type, c_ast.Struct) and node.type.type.decls == None:151 152 elif isinstance(node, c_ast.Decl) and isinstance(node.type, c_ast.Struct) and \153 154 155 return False156 157 158 159 160 161 if not (name in FORCE_STRUCT_AS_OPAQUE):162 163 if not self._is_struct_opaque(n):164 165 166 if opaque:167 168 169 170 171 # Remove "typedef struct/enum ..." without member decl (optional)172 if name:173 174 175 return code176 177 178 # init179 cbclass = ''180 cbproxy = ''181 cbdef = []182 183 184 raw_lines = self._print_node(n).splitlines()185 for idx, line in enumerate(raw_lines):186 187 188 189 190 191 fstrs = [m.group(1).strip(), m.group(2), m.group(3)]192 193 194 195 if (not m) or (not self.nodes.has_key(m.group(1))):196 197 198 fstrs = ['', m.group(2), '']199 200 raw = self._print_node(n)201 m = re.match('typedef\s+(.*)\(\*(.*)\)(\(.*\));', raw)202 if not m:203 204 205 fstrs[0] = m.group(1).strip()206 fstrs[2] = m.group(3)207 208 209 210 cbclass += ' {}\n'211 212 213 214 215 216 217 218 219 220 221 cbproxy += ' { cb->'+fstrs[1]+'('+','.join(params)+'); }\n'222 223 224 225 226 227 # trail228 229 230 231 232 233 234 235 236 237 238 239 return s240 241 242 s = ''243 for name in self.deps:244 245 246 247 248 return s249 250 251 252 253 fout = open(outdir+'/callbacks.h', 'w+')254 255 256 257 fout.write(cb[0])258 259 260 fin.close()261 fout.close()262 263 fout = open(outdir+'/callbacks.c', 'w+')264 265 266 267 fout.write(cb[1])268 269 fout.write(cb[2])270 271 272 fin.close()273 fout.close()274 275 # MAIN 66 67 def __init__(self, ast): 68 super(MyGen, self).__init__() 69 self.ast = ast 70 self.nodes = OrderedDict() 71 self.deps = list() 72 self.deps_pending = list() 73 self.deps_frozen = False 74 75 # Generate nodes map (name -> node instances) 76 for ext in self.ast.ext: 77 name = self._get_node_name(ext) 78 if name and not name.startswith(BASE_PREFIX): 79 continue 80 81 if name in self.nodes: 82 self.nodes[name].append(ext) 83 # always put typedef later, swig issue 84 if isinstance(self.nodes[name][0], c_ast.Typedef): 85 self.nodes[name].reverse() 86 else: 87 self.nodes[name] = [ext] 88 89 # Generate dependencies, they are all APIs to be exported 90 for name in self.nodes.keys(): 91 if (not name) or \ 92 ((name in FORCE_EXPORT or name.startswith(MODULE_PREFIX)) \ 93 and self._check_video(name)): 94 self._add_dep(name) 95 self.deps_frozen = True 96 97 # Override visit_IdentifierType() to collect "node name" and generate dependencies 98 # from this node's children 99 def visit_IdentifierType(self, n): 100 if not self.deps_frozen: 101 for name in n.names: self._add_dep(name) 102 return super(MyGen, self).visit_IdentifierType(n) 103 104 def _check_video(self, name): 105 if NO_VIDEO and name and ((name.find('_vid_') > 0) or (name.find('_video_') > 0)): 106 return False 107 return True 108 109 def _get_node_name(self, node): 110 s = getattr(node, 'name', None) 111 if s: 112 return s 113 if isinstance(node, c_ast.FuncDef): 114 return self._get_node_name(node.decl) 115 ss = getattr(node, 'names', None) 116 if ss: 117 s = ' '.join(ss) 118 return s 119 if getattr(node, 'type', None): 120 return self._get_node_name(node.type) 121 return s 122 123 # Trace node dependencies by recursively inspecting its children. 124 # The node itself and all its children will be listed in 'deps'. 125 def _add_dep(self, name): 126 if (name and not name.startswith(BASE_PREFIX)) or \ 127 name in self.deps or name in self.deps_pending: 128 return 129 130 if name in FORCE_STRUCT_AS_OPAQUE: 131 self.deps.append(name) 132 return 133 134 self.deps_pending.append(name) 135 for node in self.nodes[name]: 136 self.visit(node) 137 if not self.deps_pending.pop() == name: 138 print 'Error initializing dep!' 139 sys.exit(1) 140 self.deps.append(name) 141 142 # Opaque struct is identified by empty struct member declaration. 143 def _is_struct_opaque(self, node): 144 if isinstance(node, c_ast.Typedef) and isinstance(node.type, c_ast.TypeDecl) and \ 145 isinstance(node.type.type, c_ast.Struct) and node.type.type.decls == None: 146 return True 147 elif isinstance(node, c_ast.Decl) and isinstance(node.type, c_ast.Struct) and \ 148 node.type.decls == None: 149 return True 150 return False 151 152 # Check if the specified struct name is opaque. If it is, declare as zero member and 153 # tell SWIG to omit ctor/dtor. 154 def _process_opaque_struct(self, name, code): 155 opaque = True 156 if not (name in FORCE_STRUCT_AS_OPAQUE): 157 for n in self.nodes[name]: 158 if not self._is_struct_opaque(n): 159 opaque = False 160 break 161 if opaque: 162 s = '%nodefaultctor ' + name + '; %nodefaultdtor ' + name + ';\n' 163 s += 'struct ' + name + ' {};\n' 164 return s 165 166 # Remove "typedef struct/enum ..." without member decl (optional) 167 if name: 168 code = code.replace('typedef struct '+name+' '+name+';\n', '', 1) 169 code = code.replace('typedef enum '+name+' '+name+';\n', '', 1) 170 return code 171 172 def _gen_pjsua_callback(self): 173 # init 174 cbclass = '' 175 cbproxy = '' 176 cbdef = [] 177 178 n = self.nodes['pjsua_callback'][0] 179 raw_lines = self._print_node(n).splitlines() 180 for idx, line in enumerate(raw_lines): 181 if idx in [0, 1, len(raw_lines)-1]: continue 182 fstrs = [] 183 # pointer to function type format 184 m = re.match('\s+(.*)\(\*(.*)\)(\(.*\));', line) 185 if m: 186 fstrs = [m.group(1).strip(), m.group(2), m.group(3)] 187 else: 188 # typedef'd format 189 m = re.match('\s+(.*)\s+(.*);', line) 190 if (not m) or (not self.nodes.has_key(m.group(1))): 191 cbdef.append(' NULL') 192 continue 193 fstrs = ['', m.group(2), ''] 194 n = self.nodes[m.group(1)][0] 195 raw = self._print_node(n) 196 m = re.match('typedef\s+(.*)\(\*(.*)\)(\(.*\));', raw) 197 if not m: 198 cbdef.append(' NULL') 199 continue 200 fstrs[0] = m.group(1).strip() 201 fstrs[2] = m.group(3) 202 203 cbclass += ' virtual ' + ' '.join(fstrs) 204 if fstrs[0] == 'void': 205 cbclass += ' {}\n' 206 elif fstrs[1] == 'on_create_media_transport': 207 cbclass += ' { return base_tp; }\n' 208 elif fstrs[1] == 'on_call_redirected': 209 cbclass += ' { return PJSIP_REDIRECT_STOP; }\n' 210 else: 211 cbclass += ' { return 0; }\n' 212 213 cbproxy += 'static ' + ' '.join(fstrs) 214 params = re.findall('(\w+)[,\)]', fstrs[2]) 215 if fstrs[0] == 'void': 216 cbproxy += ' { cb->'+fstrs[1]+'('+','.join(params)+'); }\n' 217 else: 218 cbproxy += ' { return cb->'+fstrs[1]+'('+','.join(params)+'); }\n' 219 220 cbdef.append(' &' + fstrs[1]) 221 222 # trail 223 224 return [cbclass, cbproxy, ',\n'.join(cbdef)+'\n'] 225 226 # Generate code from the specified node. 227 def _print_node(self, node): 228 s = '' 229 if isinstance(node, c_ast.FuncDef): 230 s = self.visit(node) 231 else: 232 s = self.visit(node) 233 if s: s += ';\n' 234 return s 235 236 def go(self): 237 s = '' 238 for name in self.deps: 239 ss = '' 240 for node in self.nodes[name]: 241 ss += self._print_node(node) 242 s += self._process_opaque_struct(name, ss) 243 return s 244 245 def write_pjsua_callback(self, outdir): 246 cb = self._gen_pjsua_callback() 247 248 fout = open(outdir+'/callbacks.h', 'w+') 249 fin = open('callbacks.h.template', 'r') 250 for line in fin: 251 if line.find(r'$PJSUA_CALLBACK_CLASS$') >= 0: 252 fout.write(cb[0]) 253 else: 254 fout.write(line) 255 fin.close() 256 fout.close() 257 258 fout = open(outdir+'/callbacks.c', 'w+') 259 fin = open('callbacks.c.template', 'r') 260 for line in fin: 261 if line.find(r'$PJSUA_CALLBACK_PROXY$') >= 0: 262 fout.write(cb[1]) 263 elif line.find(r'$PJSUA_CALLBACK_DEF$') >= 0: 264 fout.write(cb[2]) 265 else: 266 fout.write(line) 267 fin.close() 268 fout.close() 269 270 # MAIN 276 271 ast = parse_file(SOURCE_PATH, use_cpp=True, cpp_path=CPP_PATH, cpp_args=CPP_CFLAGS) 277 272 #ast.show(attrnames=True, nodenames=True) -
pjproject/branches/projects/jni/pjsip/include/pjsua-lib/pjsua.h
r4549 r4557 3730 3730 * 3731 3731 * @param pool Pool to allocate memory for the string. 3732 * @param contact The string where the Contact will be stored.3732 * @param p_contact The string where the Contact will be stored. 3733 3733 * @param acc_id Account ID. 3734 3734 * @param uri Destination URI of the request. … … 3737 3737 */ 3738 3738 PJ_DECL(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, 3739 pj_str_t * contact,3739 pj_str_t *p_contact, 3740 3740 pjsua_acc_id acc_id, 3741 3741 const pj_str_t *uri); … … 3748 3748 * 3749 3749 * @param pool Pool to allocate memory for the string. 3750 * @param contact The string where the Contact will be stored.3750 * @param p_contact The string where the Contact will be stored. 3751 3751 * @param acc_id Account ID. 3752 3752 * @param rdata Incoming request. … … 3755 3755 */ 3756 3756 PJ_DECL(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, 3757 pj_str_t * contact,3757 pj_str_t *p_contact, 3758 3758 pjsua_acc_id acc_id, 3759 3759 pjsip_rx_data *rdata );
Note: See TracChangeset
for help on using the changeset viewer.