Added some missing multi-argument typemaps: (char *STRING, size_t LENGTH) and (char *STRING, int LENGTH) - Java patch is from Volker Grabsch. Elements of the primitive_types.i testcase for this moved into char_binary.i. Documentation for this enhanced.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12393 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
9adb494558
commit
ef865e06d5
15 changed files with 194 additions and 37 deletions
|
|
@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 2.0.2 (in progress)
|
||||
===========================
|
||||
|
||||
2010-01-14: wsfulton
|
||||
Added some missing multi-argument typemaps: (char *STRING, size_t LENGTH) and
|
||||
(char *STRING, int LENGTH). Documentation for this updated. Java patch from
|
||||
Volker Grabsch.
|
||||
|
||||
2010-12-30: klickverbot
|
||||
[C#, D, Java] Check for collision of parameter names with target
|
||||
language keywords when generating the director glue code.
|
||||
|
|
|
|||
|
|
@ -4401,6 +4401,49 @@ well suited for applications in which you need to create buffers,
|
|||
package binary data, etc.
|
||||
</p>
|
||||
|
||||
<H3><a name="Java_binary_char"></a>Binary data vs Strings</H3>
|
||||
|
||||
<p>
|
||||
By default SWIG handles <tt>char *</tt> as a string but there is a handy multi-argument typemap available as mentioned in <a href="Library.html#Library_nn10">Passing binary data</a>.
|
||||
The following simple example demonstrates using a byte array instead of passing the default string type and length to the wrapped function.
|
||||
</p>
|
||||
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%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");
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Calling from Java requires just the byte array to be passed in as the multi-argument typemap being applied reduces the number of arguments in the target language to one, from the original two:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
byte[] data = "hi\0jk".getBytes();
|
||||
example.binaryChar1(data);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
resulting in the output
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
$ java runme
|
||||
len: 5 data: 68 69 0 6a 6b
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Java_heap_allocations"></a>23.8.5 Overriding new and delete to allocate from Java heap</H3>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -824,20 +824,20 @@ If you have a function that expects binary data,
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
int parity(char *str, int len, int initial);
|
||||
size_t parity(char *str, size_t len, size_t initial);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
you can wrap the parameters <tt>(char *str, int len)</tt> as a single
|
||||
you can wrap the parameters <tt>(char *str, size_t len)</tt> as a single
|
||||
argument using a typemap. Just do this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%apply (char *STRING, int LENGTH) { (char *str, int len) };
|
||||
%apply (char *STRING, size_t LENGTH) { (char *str, size_t len) };
|
||||
...
|
||||
int parity(char *str, int len, int initial);
|
||||
size_t parity(char *str, size_t len, size_t initial);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -854,6 +854,7 @@ Now, in the target language, you can use binary string data like this:
|
|||
|
||||
<p>
|
||||
In the wrapper function, the passed string will be expanded to a pointer and length parameter.
|
||||
The <tt>(char *STRING, int LENGTH)</tt> multi-argument typemap is also available in addition to <tt>(char *STRING, size_t LENGTH)</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Library_nn11"></a>8.3.3 Using %newobject to release memory</H3>
|
||||
|
|
|
|||
29
Examples/test-suite/char_binary.i
Normal file
29
Examples/test-suite/char_binary.i
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
A test case for testing non null terminated char pointers.
|
||||
*/
|
||||
|
||||
%module char_binary
|
||||
|
||||
%apply (char *STRING, size_t LENGTH) { (const char *str, size_t len) }
|
||||
|
||||
%inline %{
|
||||
struct Test {
|
||||
size_t strlen(const char *str, size_t len) {
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
typedef char namet[5];
|
||||
namet var_namet;
|
||||
|
||||
typedef char* pchar;
|
||||
pchar var_pchar;
|
||||
%}
|
||||
|
||||
// Remove string handling typemaps and treat as pointer
|
||||
%typemap(freearg) SWIGTYPE * ""
|
||||
%apply SWIGTYPE * { char * }
|
||||
|
||||
%include "carrays.i"
|
||||
%array_functions(char, pchar);
|
||||
|
||||
24
Examples/test-suite/java/char_binary_runme.java
Normal file
24
Examples/test-suite/java/char_binary_runme.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import char_binary.*;
|
||||
|
||||
public class char_binary_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("char_binary");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
Test t = new Test();
|
||||
byte[] hile = "hile".getBytes();
|
||||
byte[] hil0 = "hil\0".getBytes();
|
||||
if (t.strlen(hile) != 4)
|
||||
throw new RuntimeException("bad multi-arg typemap");
|
||||
|
||||
if (t.strlen(hil0) != 4)
|
||||
throw new RuntimeException("bad multi-arg typemap");
|
||||
}
|
||||
}
|
||||
32
Examples/test-suite/perl5/char_binary_runme.pl
Executable file
32
Examples/test-suite/perl5/char_binary_runme.pl
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 7;
|
||||
BEGIN { use_ok('char_binary') }
|
||||
require_ok('char_binary');
|
||||
|
||||
my $t = char_binary::Test->new();
|
||||
|
||||
is($t->strlen('hile'), 4, "string typemap");
|
||||
|
||||
is($t->strlen("hil\0"), 4, "string typemap");
|
||||
|
||||
#
|
||||
# creating a raw char*
|
||||
#
|
||||
my $pc = char_binary::new_pchar(5);
|
||||
char_binary::pchar_setitem($pc, 0, 'h');
|
||||
char_binary::pchar_setitem($pc, 1, 'o');
|
||||
char_binary::pchar_setitem($pc, 2, 'l');
|
||||
char_binary::pchar_setitem($pc, 3, 'a');
|
||||
char_binary::pchar_setitem($pc, 4, 0);
|
||||
|
||||
|
||||
is($t->strlen($pc), 4, "string typemap");
|
||||
|
||||
$char_binary::var_pchar = $pc;
|
||||
is($char_binary::var_pchar, "hola", "pointer case");
|
||||
|
||||
$char_binary::var_namet = $pc;
|
||||
is($char_binary::var_namet, "hola", "pointer case");
|
||||
|
||||
char_binary::delete_pchar($pc);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 54;
|
||||
use Test::More tests => 51;
|
||||
BEGIN { use_ok('primitive_types') }
|
||||
require_ok('primitive_types');
|
||||
|
||||
|
|
@ -179,11 +179,6 @@ $t->{var_namet} = 'hol';
|
|||
is($t->{var_namet}, 'hol', "namet");
|
||||
|
||||
|
||||
is($t->strlen('hile'), 4, "string typemap");
|
||||
|
||||
is($t->strlen("hil\0"), 4, "string typemap");
|
||||
|
||||
|
||||
$primitive_types::var_char = "\0";
|
||||
is($primitive_types::var_char, "\0", "char '0' case");
|
||||
|
||||
|
|
@ -220,8 +215,6 @@ primitive_types::pchar_setitem($pc, 3, 'a');
|
|||
primitive_types::pchar_setitem($pc, 4, 0);
|
||||
|
||||
|
||||
is($t->strlen($pc), 4, "string typemap");
|
||||
|
||||
$primitive_types::var_pchar = $pc;
|
||||
is($primitive_types::var_pchar, "hola", "pointer case");
|
||||
|
||||
|
|
|
|||
|
|
@ -355,8 +355,6 @@ macro(size_t, pfx, sizet)
|
|||
%enddef
|
||||
|
||||
|
||||
%apply (char *STRING, int LENGTH) { (const char *str, size_t len) }
|
||||
|
||||
%inline {
|
||||
struct Foo
|
||||
{
|
||||
|
|
@ -464,15 +462,8 @@ macro(size_t, pfx, sizet)
|
|||
|
||||
%test_prim_types_ovr(ovr_decl, ovr)
|
||||
|
||||
size_t strlen(const char *str, size_t len)
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
static const double stc_double;
|
||||
static const double stc_float;
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct TestDirector
|
||||
|
|
|
|||
36
Examples/test-suite/python/char_binary_runme.py
Normal file
36
Examples/test-suite/python/char_binary_runme.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from char_binary import *
|
||||
|
||||
t = Test()
|
||||
if t.strlen('hile') != 4:
|
||||
print t.strlen('hile')
|
||||
raise RuntimeError, "bad multi-arg typemap"
|
||||
|
||||
if t.strlen('hil\0') != 4:
|
||||
raise RuntimeError, "bad multi-arg typemap"
|
||||
|
||||
#
|
||||
# creating a raw char*
|
||||
#
|
||||
pc = new_pchar(5)
|
||||
pchar_setitem(pc, 0, 'h')
|
||||
pchar_setitem(pc, 1, 'o')
|
||||
pchar_setitem(pc, 2, 'l')
|
||||
pchar_setitem(pc, 3, 'a')
|
||||
pchar_setitem(pc, 4, 0)
|
||||
|
||||
|
||||
if t.strlen(pc) != 4:
|
||||
raise RuntimeError, "bad multi-arg typemap"
|
||||
|
||||
cvar.var_pchar = pc
|
||||
if cvar.var_pchar != "hola":
|
||||
print cvar.var_pchar
|
||||
raise RuntimeError, "bad pointer case"
|
||||
|
||||
cvar.var_namet = pc
|
||||
#if cvar.var_namet != "hola\0":
|
||||
if cvar.var_namet != "hola":
|
||||
raise RuntimeError, "bad pointer case"
|
||||
|
||||
delete_pchar(pc)
|
||||
|
||||
|
|
@ -188,14 +188,6 @@ if t.var_namet != 'hol':
|
|||
raise RuntimeError
|
||||
|
||||
|
||||
if t.strlen('hile') != 4:
|
||||
print t.strlen('hile')
|
||||
raise RuntimeError, "bad string typemap"
|
||||
|
||||
if t.strlen('hil\0') != 4:
|
||||
raise RuntimeError, "bad string typemap"
|
||||
|
||||
|
||||
cvar.var_char = '\0'
|
||||
if cvar.var_char != '\0':
|
||||
raise RuntimeError, "bad char '0' case"
|
||||
|
|
@ -244,9 +236,6 @@ pchar_setitem(pc, 3, 'a')
|
|||
pchar_setitem(pc, 4, 0)
|
||||
|
||||
|
||||
if t.strlen(pc) != 4:
|
||||
raise RuntimeError, "bad string typemap"
|
||||
|
||||
cvar.var_pchar = pc
|
||||
if cvar.var_pchar != "hola":
|
||||
print cvar.var_pchar
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ $result = C_SCHEME_UNDEFINED;
|
|||
* String & length
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
%typemap(in) (char *STRING, int LENGTH) {
|
||||
%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
|
||||
if ($input == C_SCHEME_FALSE) {
|
||||
swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use a null/#f string for a char*, int arguments");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ typedef unsigned long SCM;
|
|||
* String & length
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
%typemap(in) (char *STRING, int LENGTH) {
|
||||
%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
|
||||
size_t temp;
|
||||
$1 = ($1_ltype) gh_scm2newstr($input, &temp);
|
||||
$2 = ($2_ltype) temp;
|
||||
|
|
|
|||
|
|
@ -1290,6 +1290,21 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
|
|||
/* const pointers */
|
||||
%apply SWIGTYPE * { SWIGTYPE *const }
|
||||
|
||||
/* String & length */
|
||||
%typemap(jni) (char *STRING, size_t LENGTH) "jbyteArray"
|
||||
%typemap(jtype) (char *STRING, size_t LENGTH) "byte[]"
|
||||
%typemap(jstype) (char *STRING, size_t LENGTH) "byte[]"
|
||||
%typemap(javain) (char *STRING, size_t LENGTH) "$javainput"
|
||||
%typemap(freearg) (char *STRING, size_t LENGTH) ""
|
||||
%typemap(in) (char *STRING, size_t LENGTH) {
|
||||
$1 = (char *) JCALL2(GetByteArrayElements, jenv, $input, 0);
|
||||
$2 = (size_t) JCALL1(GetArrayLength, jenv, $input);
|
||||
}
|
||||
%typemap(argout) (char *STRING, size_t LENGTH) {
|
||||
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, 0);
|
||||
}
|
||||
%apply (char *STRING, size_t LENGTH) { (char *STRING, int LENGTH) }
|
||||
|
||||
/* java keywords */
|
||||
%include <javakw.swg>
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@
|
|||
$1 = ($1_ltype) Z_STRVAL_PP($input);
|
||||
}
|
||||
|
||||
%typemap(in) (char *STRING, int LENGTH)
|
||||
{
|
||||
%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
|
||||
convert_to_string_ex($input);
|
||||
$1 = ($1_ltype) Z_STRVAL_PP($input);
|
||||
$2 = ($2_ltype) Z_STRLEN_PP($input);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ extern "C" {
|
|||
* String & length
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
%typemap(in, pikedesc="tStr") (char *STRING, int LENGTH) {
|
||||
%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
|
||||
if ($input.type != T_STRING)
|
||||
Pike_error("Bad argument: Expected a string.\n");
|
||||
$1 = ($1_ltype) STR0($input.u.string);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue