From: Adam B <ad...@vi...> - 2012-09-04 21:39:17
|
Hello all, I'm trying to figure out how to apply multiple typemaps to a single C function. Let's say I have a C function like this: void writeBytes(unsigned char * theBytes, int size); My goal is to make the target language(s) pass in raw bytes, instead of a string so I do what the SWIG docs tell me to: ------------- mymodule.i ------------ %module mymodule %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; void writeBytes(unsigned char * theBytes, int size); ----------------------------------------- This works perfectly. Both Python and Java are able to pass in raw bytes. But then I realized that if my java program passes in a 'null' byte-array the JVM segfaults in the JNI code when calling GetByteArrayElements(). To fix this I would like to have SWIG generate a null-check for me using the 'javain' typemap. (Note: the NONNULL typemap provided by constraints.i doesn't work because it does the check too late - after GetByteArrayElements is called.) This typemap generates a null-check in the java proxy class code exactly where I want it. ------------- mymodule.i ------------ %module mymodule %typemap(javain, pre="if ($javainput == null) throw new NullPointerException();") unsigned char * theBytes "$javainput"; void writeBytes(unsigned char * theBytes, int size); ----------------------------------------- My question is, how do I apply BOTH these typemaps to the function. Simply listing them both is the intuitive solution but it does not work. ------------- mymodule.i ------------ %module mymodule //Doesn't work! %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; %typemap(javain, pre="if ($javainput == null) throw new NullPointerException();") unsigned char * theBytes "$javainput"; void writeBytes(unsigned char * theBytes, int size); ----------------------------------------- Any help you could offer would be much appreciated. Thanks - Adam B. Videx, Inc. | 1105 NE Circle Blvd. | Corvallis, OR 97330 | (541) 738-5500 This email is intended only for the addressee(s) and may include material that is privileged, confidential, and protected from disclosure. No contract is intended. ©2012 Videx, Inc. |
From: Adam B <ad...@vi...> - 2012-09-06 21:53:17
|
Anybody? On 09/04/2012 02:09 PM, Adam B wrote: > Hello all, > > I'm trying to figure out how to apply multiple typemaps to a single C function. Let's say I have a C function like this: > > void writeBytes(unsigned char * theBytes, int size); > > My goal is to make the target language(s) pass in raw bytes, instead of a string so I do what the SWIG docs tell me to: > > ------------- mymodule.i ------------ > %module mymodule > > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > This works perfectly. Both Python and Java are able to pass in raw bytes. > > But then I realized that if my java program passes in a 'null' byte-array the JVM segfaults in the JNI code when calling GetByteArrayElements(). To fix this I would like to have SWIG generate a null-check for me using the 'javain' typemap. (Note: the NONNULL typemap provided by constraints.i doesn't work because it does the check too late - after GetByteArrayElements is called.) > > This typemap generates a null-check in the java proxy class code exactly where I want it. > > ------------- mymodule.i ------------ > %module mymodule > > %typemap(javain, pre="if ($javainput == null) throw new NullPointerException();") unsigned char * theBytes "$javainput"; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > My question is, how do I apply BOTH these typemaps to the function. Simply listing them both is the intuitive solution but it does not work. > > ------------- mymodule.i ------------ > %module mymodule > > //Doesn't work! > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; > %typemap(javain, pre="if ($javainput == null) throw new NullPointerException();") unsigned char * theBytes "$javainput"; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > > Any help you could offer would be much appreciated. > Thanks > - Adam B. > Videx, Inc. | 1105 NE Circle Blvd. | Corvallis, OR 97330 | (541) 738-5500 This email is intended only for the addressee(s) and may include material that is privileged, confidential, and protected from disclosure. No contract is intended. ©2012 Videx, Inc. |
From: William S F. <ws...@fu...> - 2012-09-07 06:19:29
|
On 04/09/12 22:09, Adam B wrote: > Hello all, > > I'm trying to figure out how to apply multiple typemaps to a single C > function. Let's say I have a C function like this: > > void writeBytes(unsigned char * theBytes, int size); > > My goal is to make the target language(s) pass in raw bytes, instead of > a string so I do what the SWIG docs tell me to: > > ------------- mymodule.i ------------ > %module mymodule > > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, > int size) }; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > This works perfectly. Both Python and Java are able to pass in raw bytes. > > But then I realized that if my java program passes in a 'null' > byte-array the JVM segfaults in the JNI code when calling > GetByteArrayElements(). To fix this I would like to have SWIG generate > a null-check for me using the 'javain' typemap. (Note: the NONNULL > typemap provided by constraints.i doesn't work because it does the check > too late - after GetByteArrayElements is called.) > > This typemap generates a null-check in the java proxy class code exactly > where I want it. > > ------------- mymodule.i ------------ > %module mymodule > > %typemap(javain, pre="if ($javainput == null) throw new > NullPointerException();") unsigned char * theBytes "$javainput"; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > My question is, how do I apply BOTH these typemaps to the function. > Simply listing them both is the intuitive solution but it does not work. > > ------------- mymodule.i ------------ > %module mymodule > > //Doesn't work! > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, > int size) }; > %typemap(javain, pre="if ($javainput == null) throw new > NullPointerException();") unsigned char * theBytes "$javainput"; > void writeBytes(unsigned char * theBytes, int size); > > ----------------------------------------- > > The typemap should be defined before %apply in order for it to be applied and it should be defined for (char *STRING, size_t LENGTH): %typemap(javain, pre="if ($javainput == null) throw new NullPointerException();") (char *STRING, size_t LENGTH) "$javainput"; %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; Really the 'in' typemap should handle null as input so I've fixed this for the next release. However, I've changed it to accept NULL for the char * parameter without segfaulting in the JNI marshalling. But you don't want to accept NULL as input, so you could instead check for this in the 'in' typemap. You can simply override the default one supplied by SWIG and use: %typemap(in) (char *STRING, size_t LENGTH) { if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_name is null"); return $null; } $1 = (char *) JCALL2(GetByteArrayElements, jenv, $input, 0); $2 = (size_t) JCALL1(GetArrayLength, jenv, $input); } %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; William |
From: Adam B <ad...@vi...> - 2012-09-07 23:24:52
|
On 09/06/2012 11:19 PM, William S Fulton wrote: > On 04/09/12 22:09, Adam B wrote: >> Hello all, >> >> I'm trying to figure out how to apply multiple typemaps to a single C >> function. Let's say I have a C function like this: >> >> void writeBytes(unsigned char * theBytes, int size); >> >> My goal is to make the target language(s) pass in raw bytes, instead of >> a string so I do what the SWIG docs tell me to: >> >> ------------- mymodule.i ------------ >> %module mymodule >> >> %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, >> int size) }; >> void writeBytes(unsigned char * theBytes, int size); >> >> ----------------------------------------- >> >> This works perfectly. Both Python and Java are able to pass in raw bytes. >> >> But then I realized that if my java program passes in a 'null' >> byte-array the JVM segfaults in the JNI code when calling >> GetByteArrayElements(). To fix this I would like to have SWIG generate >> a null-check for me using the 'javain' typemap. (Note: the NONNULL >> typemap provided by constraints.i doesn't work because it does the check >> too late - after GetByteArrayElements is called.) >> >> This typemap generates a null-check in the java proxy class code exactly >> where I want it. >> >> ------------- mymodule.i ------------ >> %module mymodule >> >> %typemap(javain, pre="if ($javainput == null) throw new >> NullPointerException();") unsigned char * theBytes "$javainput"; >> void writeBytes(unsigned char * theBytes, int size); >> >> ----------------------------------------- >> >> My question is, how do I apply BOTH these typemaps to the function. >> Simply listing them both is the intuitive solution but it does not work. >> >> ------------- mymodule.i ------------ >> %module mymodule >> >> //Doesn't work! >> %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, >> int size) }; >> %typemap(javain, pre="if ($javainput == null) throw new >> NullPointerException();") unsigned char * theBytes "$javainput"; >> void writeBytes(unsigned char * theBytes, int size); >> >> ----------------------------------------- >> >> > The typemap should be defined before %apply in order for it to be applied and it should be defined for (char *STRING, size_t LENGTH): > > %typemap(javain, pre="if ($javainput == null) throw new > NullPointerException();") (char *STRING, size_t LENGTH) "$javainput"; > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, > int size) }; > > Really the 'in' typemap should handle null as input so I've fixed this for the next release. However, I've changed it to accept NULL for the char * parameter without segfaulting in the JNI marshalling. But you don't want to accept NULL as input, so you could instead check for this in the 'in' typemap. You can simply override the default one supplied by SWIG and use: > > %typemap(in) (char *STRING, size_t LENGTH) { > if (!$input) { > SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_name is null"); > return $null; > } > $1 = (char *) JCALL2(GetByteArrayElements, jenv, $input, 0); > $2 = (size_t) JCALL1(GetArrayLength, jenv, $input); > } > %apply (char *STRING, size_t LENGTH) { (unsigned char * theBytes, int size) }; > > William Thanks for the reply, William. I'll try your suggestion ASAP. I'm also glad to hear future versions will avoid the segfault by default. Videx, Inc. | 1105 NE Circle Blvd. | Corvallis, OR 97330 | (541) 738-5500 This email is intended only for the addressee(s) and may include material that is privileged, confidential, and protected from disclosure. No contract is intended. ©2012 Videx, Inc. |