Menu

#793 Swig, perl5 and union

None
closed
perl (97)
5
2023-09-10
2007-01-26
J. Bedouet
No

Hello,

The next example, given in the SWIG documentation, doesn't work at home. I downloaded the last version of swig but the C function which wraps the setter of an union in a structure is not generated. I show you.

$ swig -version

SWIG Version 1.3.31

Compiled with g++ [i686-pc-linux-gnu]
Please see http://www.swig.org for reporting bugs and further information

$ more test.i
%module Test

typedef struct Object {
int objtype;
union {
int ivalue;
double dvalue;
char *strvalue;
void *ptrvalue;
} intRep;
} Object;

$ swig -perl5 test.i

$ grep Object_objtype_set *
Test.pm:*swig_objtype_set = *Testc::Object_objtype_set;
test_wrap.c:XS(_wrap_Object_objtype_set) {
test_wrap.c: SWIG_croak("Usage: Object_objtype_set(self,objtype);");
test_wrap.c: SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Object_objtype_set" "', argument " "1"" of type '" "Object *""'");
test_wrap.c: SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Object_objtype_set" "', argument " "2"" of type '" "int""'");
test_wrap.c:{"Testc::Object_objtype_set", _wrap_Object_objtype_set},

$ grep Object_intRep_get *
Test.pm:*swig_intRep_get = *Testc::Object_intRep_get;
test_wrap.c:XS(_wrap_Object_intRep_get) {
test_wrap.c: SWIG_croak("Usage: Object_intRep_get(self);");
test_wrap.c: SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Object_intRep_get" "', argument " "1"" of type '" "Object *""'");
test_wrap.c:{"Testc::Object_intRep_get", _wrap_Object_intRep_get},

$ grep Object_intRep_set *
Test.pm:*swig_intRep_set = *Testc::Object_intRep_set;

The equivalent code doesn't appear in the file test_wrap.c.

Thank you for your help,

Judi

Discussion

  • Olly Betts

    Olly Betts - 2022-02-08

    Still reproducible with current git.

     
  • William Fulton

    William Fulton - 2023-09-10
    • status: open --> closed
    • assigned_to: William Fulton
    • Group: -->
     
  • William Fulton

    William Fulton - 2023-09-10

    The union variable name is called intRep and is an anonymous union, that is, it does not have any type name. It is thus not possible to create a type outside of Object to assign to intRep. Consider a small change to give the union a type name, say IntRepType as follows:

    typedef struct Object {
      int objtype;
      union IntRepType {
        int ivalue;
        double dvalue;
        char *strvalue;
        void *ptrvalue;
      } intRep;
    } Object;
    
    void tester() {
      /* approach (1) */
      obj.intRep.dvalue = 1.23;
    
      /* approach (2) */
      union IntRepType irt;
      irt.dvalue = 2.34;
      obj.intRep = irt;
    }
    

    You can see using C code that there are two approaches to setting a value in intRep. Equivalents in perl are:

    my $obj = example::Object->new();
    $obj->{objtype} = 11;
    
    # approach (1)
    $obj->{intRep}->{dvalue} = 3.45;
    
    # approach (2)
    my $irt = example::IntRepType->new();
    $irt->{dvalue} = 4.56;
    $obj->{intRep} = $irt;
    

    An Object_intRep_set wrapper is generated which takes type IntRepType as desired.

    With the example as originally posted, only approach (1) is available in C and so SWIG can only provide approach (1) from Perl too. Hence there is no Object_intRep_set wrapper.

     

Log in to post a comment.