How can I make Swig correctly wrap a char* buffer that is modified in C as a Java Something-or-other
        Posted  
        
            by Ukko
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Ukko
        
        
        
        Published on 2010-04-29T19:09:34Z
        Indexed on 
            2010/04/29
            20:47 UTC
        
        
        Read the original article
        Hit count: 412
        
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
buffis a character bufferlenis the length of the data in the buffercursethe 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?
© Stack Overflow or respective owner