SWIG technology for nulling unsigned binary data

I have a C function that returns an unsigned char * that represents binary data. I noticed in the documentation that SWIG has a nice sample card for processing binary data as input to function C, but what about when function C returns binary data and its unsigned? Any ideas?

swig.i:

%apply (char *STRING, size_t LENGTH) { (const char data[], size_t len) } %inline %{ void binaryChar1(const char data[], size_t len) { printf("len: %d data: ", len); for (size_t i=0; i<len; ++i) printf("%x ", data[i]); printf("\n"); } %} 

Java:

 byte[] data = "hi\0jk".getBytes(); example.binaryChar1(data); 

Example:

  enw_resultrow_t *result_row = getResultRow(); unsigned char *blob; while ((blob = getBinaryFromRow(result_row, &length))) { char fname[32]; FILE *fp; i++; snprintf (fname, sizeof(fname), "FileXYZ", i); printf ("Blob from %d:%s is saved in %s has %d bytes\n", i, aSender?inet_ntoa(aSender->sin_addr):"???", fname, length); if ((fp = fopen (fname, "w"))) { l = fwrite (blob, sizeof (unsigned char), length, fp); printf("Successfully wrote %d bytes to file\n", l); fclose (fp); } else { printf("Error writing file"); } } 
+7
source share
2 answers

I created a test case that reflects what you are trying to do (I think):

 #include <stdlib.h> enum thing { ONE=1, TWO=2, THREE=3 }; static signed char *get_data(enum thing t, size_t *len) { *len = (size_t)t; signed char *ret = malloc(sizeof(signed char) * (*len)); for (size_t i = 0; i < *len; ++i) { ret[i] = i; } return ret; } 

To wrap get_data() , I used the following interface:

 %module test %{ #include "test.h" %} %typemap(jni) signed char *get_data "jbyteArray" %typemap(jtype) signed char *get_data "byte[]" %typemap(jstype) signed char *get_data "byte[]" %typemap(javaout) signed char *get_data { return $jnicall; } %typemap(in,numinputs=0,noblock=1) size_t *len { size_t length=0; $1 = &length; } %typemap(out) signed char *get_data { $result = JCALL1(NewByteArray, jenv, length); JCALL4(SetByteArrayRegion, jenv, $result, 0, length, $1); } %include "test.h" 

This basically means that the return type from the get_data function is a Java array directly from the JNI code completely through the SWIG proxy. After that, it sets a temporary size_t called length , which will be used to call the real C function and save the result. (I did not see noblock , before I saw this answer to another question , it tells SWIG not to make the typemap argument independent and, as such, could be one size_t *len parameter for this function, take a look at what it does with created wrapper code if you're interested).

After this set, it remains only to select the array using a JNI call and copy some values ​​into it.

I tested this with:

 public class run { public static void main(String[] argv) { System.loadLibrary("test"); byte[] test1 = test.get_data(thing.ONE); System.out.println(test1.length); System.out.println(test1 + ": " + test1[0]); byte[] test2 = test.get_data(thing.TWO); System.out.println(test2.length); System.out.println(test2 + ": " + test2[0] + ", " + test2[1]); byte[] test3 = test.get_data(thing.THREE); System.out.println(test3.length); System.out.println(test3 + ": " + test3[0] + ", " + test3[1] + ", " + test3[2]); } } 

Which then gave:

  one
 [ B@525483cd : 0
 2
 [ B@2a9931f5 : 0, 1
 3
 [ B@2f9ee1ac : 0, 1, 2

I changed a bit by making my signed char . If you want to do this unsigned, you need to either use casting (beware of losing the sign at best), or short / int with the appropriate conversion.

Be careful about owning memory in your real code.

+5
source

I think you do not need to implement your own mechanism. swig provides a module named 'cdata.i'. You must include this in the interface definition file.

Once you enable this, it gives two functions cdata () and memmove (). Given void * and the length of the binary data, cdata () converts it to the string type of the target language. memmove () is the opposite. Given the type of string, it will copy the contents of the string (including embedded null bytes) into type C void *.

Processing binary data with this module becomes very simple. Hope this is what you need.

+1
source

All Articles