How can I make Swig correctly wrap a char* buffer that is modified in C as a Java Something-or-other
- by Ukko
I am trying to wrap some legacy code for use in Java and I was quite happy to see that Swig was able to handle the header file and it generate a great wrapper that almost works. Now I am looking for the deep magic that will make it really work.
In C I have a function that looks like this
DLL_IMPORT int DustyVoodoo(char *buff, int len, char *curse);
This integer returned by this function is an error code in case it fails. The arguments are
buff is a character buffer
len is the length of the data in the buffer
curse the another character buffer that contains the result of calling DustyVoodoo
So, you can see where this is going, the result is actually coming back via the third argument. Also len is confusing since it may be the length of both buffers, they are always allocated as being the same size in calling code but given what DustyVoodoo does I don't think that they need be the same. To be safe both buffers should be the same size in practice, say 512 chars.
The C code generated for the binding is as follows:
SWIGEXPORT jint JNICALL Java_pemapiJNI_DustyVoodoo(JNIEnv *jenv, jclass jcls, jstring
jarg1, jint jarg2, jstring jarg3) {
jint jresult = 0 ;
char *arg1 = (char *) 0 ;
int arg2 ;
char *arg3 = (char *) 0 ;
int result;
(void)jenv;
(void)jcls;
arg1 = 0;
if (jarg1) {
arg1 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg1, 0);
if (!arg1) return 0;
}
arg2 = (int)jarg2;
arg3 = 0;
if (jarg3) {
arg3 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg3, 0);
if (!arg3) return 0;
}
result = (int)PemnEncrypt(arg1,arg2,arg3);
jresult = (jint)result;
if (arg1) (*jenv)->ReleaseStringUTFChars(jenv, jarg1, (const char *)arg1);
if (arg3) (*jenv)->ReleaseStringUTFChars(jenv, jarg3, (const char *)arg3);
return jresult;
}
It is correct for what it does; however, it misses the fact that cursed is not just an input, it is altered by the function and should be returned as an output. It also does not know that the java Strings are really buffers and should be backed by a suitably sized array.
I think that Swig can do the right thing here, I just can't figure out from the documentation how to tell Swig what it needs to know. Any typemap masers in the house?