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: 356

Filed under:
|
|
|

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?

© Stack Overflow or respective owner

Related posts about java

Related posts about c