typedef / %rename problem in struct

View: New views
4 Messages — Rating Filter:   Alert me  

typedef / %rename problem in struct

by MakaMaka :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
I'm having trouble wrapping a more complicated version of the code below.  Specifically, SWIG is defining an outer__inner struct, but using _inner as the type for inner in the set / get methods it generates.  I've tried to explicitly %rename _inner to outer__inner but SWIG is ignore the directive for some reason.

Does anybody know a way around this problem, short of redefining the struct (that's not an option as the struct is autogenerated as part of a much, much larger project that I have little control over)?

Thanks in advance.

pytest.i
-------------------------------
%module pytest
%{
#include "pytest.h"
%}

%include "pytest.h"
-------------------------------

pytest.h
-------------------------------
typedef unsigned char UINT8;

struct outer {

    typedef struct __inner {
        UINT8 Mode: 2;
        UINT8 State: 2;
        UINT8 Fire: 1;
        UINT8 Spare: 3;
    } _inner;

    _inner inner;
};
-------------------------------

||=== pytest, Debug ===|
pytest_wrap.cxx||In function `PyObject* _wrap_outer_inner_set(PyObject*, PyObject*)':|
pytest_wrap.cxx|2973|error: `_inner' was not declared in this scope|
pytest_wrap.cxx|2973|error: expected `;' before "arg2"|
pytest_wrap.cxx|2995|error: `temp' was not declared in this scope|
pytest_wrap.cxx|2995|error: `_inner' is not a type|
pytest_wrap.cxx|2995|error: expected `>' before '*' token|
pytest_wrap.cxx|2995|error: expected `(' before '*' token|
pytest_wrap.cxx|2995|error: expected primary-expression before '>' token|
pytest_wrap.cxx|2995|error: expected `)' before ';' token|
pytest_wrap.cxx|2996|error: `arg2' was not declared in this scope|
pytest_wrap.cxx|2997|error: type `<type error>' argument given to `delete', expected pointer|
pytest_wrap.cxx|2996|warning: unused variable 'arg2'|
pytest_wrap.cxx|3000|error: `arg2' was not declared in this scope|
pytest_wrap.cxx|3000|warning: unused variable 'arg2'|
pytest_wrap.cxx||In function `PyObject* _wrap_outer_inner_get(PyObject*, PyObject*)':|
pytest_wrap.cxx|3014|error: `_inner' was not declared in this scope|
pytest_wrap.cxx|3014|error: expected `;' before "result"|
pytest_wrap.cxx|3022|error: `result' was not declared in this scope|
pytest_wrap.cxx|3023|error: `_inner' is not a type|
pytest_wrap.cxx|3023|error: ISO C++ forbids declaration of `type name' with no type|
pytest_wrap.cxx|3023|error: expected `>' before "_inner"|
pytest_wrap.cxx|3023|error: expected `(' before "_inner"|
pytest_wrap.cxx|3023|error: expected primary-expression before '>' token|
pytest_wrap.cxx||In function `PyObject* _wrap_outer__inner_get(PyObject*, PyObject*)':|
pytest_wrap.cxx|3044|error: invalid use of `outer::_inner'|
||=== Build finished: 20 errors, 2 warnings ===|

Re: typedef / %rename problem in struct

by David Piepgrass :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Hi,
> I'm having trouble wrapping a more complicated version of the code
> below.
> Specifically, SWIG is defining an outer__inner struct, but using _inner
> as
> the type for inner in the set / get methods it generates.  I've tried
> to
> explicitly %rename _inner to outer__inner but SWIG is ignore the
> directive
> for some reason.
>
> Does anybody know a way around this problem, short of redefining the
> struct
> (that's not an option as the struct is autogenerated as part of a much,
> much
> larger project that I have little control over)?

Sounds like a bug to me. However, %rename is behaving correctly: it renames the symbol in the target language, it does not change references to the symbol on the C/C++ side.

Try this workaround:

%{
#include "pytest.h"
typedef outer::_inner _inner;
%}

> pytest.i
> -------------------------------
> %module pytest
> %{
> #include "pytest.h"
> %}
>
> %include "pytest.h"
> -------------------------------
>
> pytest.h
> -------------------------------
> typedef unsigned char UINT8;
>
> struct outer {
>
>     typedef struct __inner {
>         UINT8 Mode: 2;
>         UINT8 State: 2;
>         UINT8 Fire: 1;
>         UINT8 Spare: 3;
>     } _inner;
>
>     _inner inner;
> };
> -------------------------------
>
> ||=== pytest, Debug ===|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer_inner_set(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|2973|error: `_inner' was not declared in this scope|
> pytest_wrap.cxx|2973|error: expected `;' before "arg2"|
> pytest_wrap.cxx|2995|error: `temp' was not declared in this scope|
> pytest_wrap.cxx|2995|error: `_inner' is not a type|
> pytest_wrap.cxx|2995|error: expected `>' before '*' token|
> pytest_wrap.cxx|2995|error: expected `(' before '*' token|
> pytest_wrap.cxx|2995|error: expected primary-expression before '>'
> token|
> pytest_wrap.cxx|2995|error: expected `)' before ';' token|
> pytest_wrap.cxx|2996|error: `arg2' was not declared in this scope|
> pytest_wrap.cxx|2997|error: type `<type error>' argument given to
> `delete',
> expected pointer|
> pytest_wrap.cxx|2996|warning: unused variable 'arg2'|
> pytest_wrap.cxx|3000|error: `arg2' was not declared in this scope|
> pytest_wrap.cxx|3000|warning: unused variable 'arg2'|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer_inner_get(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|3014|error: `_inner' was not declared in this scope|
> pytest_wrap.cxx|3014|error: expected `;' before "result"|
> pytest_wrap.cxx|3022|error: `result' was not declared in this scope|
> pytest_wrap.cxx|3023|error: `_inner' is not a type|
> pytest_wrap.cxx|3023|error: ISO C++ forbids declaration of `type name'
> with
> no type|
> pytest_wrap.cxx|3023|error: expected `>' before "_inner"|
> pytest_wrap.cxx|3023|error: expected `(' before "_inner"|
> pytest_wrap.cxx|3023|error: expected primary-expression before '>'
> token|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer__inner_get(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|3044|error: invalid use of `outer::_inner'|
> ||=== Build finished: 20 errors, 2 warnings ===|
> --
> View this message in context: http://www.nabble.com/typedef----rename-
> problem-in-struct-tp25931898p25931898.html
> Sent from the swig-user mailing list archive at Nabble.com.
>
>
> -----------------------------------------------------------------------
> -------
> Come build with us! The BlackBerry(R) Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart
> your
> developing skills, take BlackBerry mobile applications to market and
> stay
> ahead of the curve. Join us from November 9 - 12, 2009. Register now!
> http://p.sf.net/sfu/devconference
> _______________________________________________
> Swig-user mailing list
> Swig-user@...
> https://lists.sourceforge.net/lists/listinfo/swig-user

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

Re: typedef / %rename problem in struct

by MakaMaka :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok, I added the typedef and while it solves the initial problem, it creates another:

Error 1 error C2273: 'function-style cast' : illegal as right side of '->' operator

Which is in response to this swig generated wrapper:

SWIGINTERN PyObject *_wrap_outer__inner_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  outer *arg1 = (outer *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject * obj0 = 0 ;
  outer__inner *result = 0 ;
 
  if (!PyArg_ParseTuple(args,(char *)"O:outer__inner_get",&obj0)) SWIG_fail;
  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_outer, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "outer__inner_get" "', argument " "1"" of type '" "outer *""'");
  }
  arg1 = reinterpret_cast< outer * >(argp1);
  result = (outer__inner *)& ((arg1)->_inner);
  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_outer__inner, 0 |  0 );
  return resultobj;
fail:
  return NULL;
}

This line:

result = (outer__inner *)& ((arg1)->_inner)

is causing the problem - specifically the _inner.  What's happening as far as I can tell is that SWIG is trying to generate a wrapper allowing access to _inner now, which is a type not a value, so it's illegal.

Is there a way to tell swig not to do this?  I've tried %ignore outer::__inner to no avail, but perhaps I'm doing it wrong.

Thanks.



David Piepgrass wrote:
> Hi,
> I'm having trouble wrapping a more complicated version of the code
> below.
> Specifically, SWIG is defining an outer__inner struct, but using _inner
> as
> the type for inner in the set / get methods it generates.  I've tried
> to
> explicitly %rename _inner to outer__inner but SWIG is ignore the
> directive
> for some reason.
>
> Does anybody know a way around this problem, short of redefining the
> struct
> (that's not an option as the struct is autogenerated as part of a much,
> much
> larger project that I have little control over)?

Sounds like a bug to me. However, %rename is behaving correctly: it renames the symbol in the target language, it does not change references to the symbol on the C/C++ side.

Try this workaround:

%{
#include "pytest.h"
typedef outer::_inner _inner;
%}

> pytest.i
> -------------------------------
> %module pytest
> %{
> #include "pytest.h"
> %}
>
> %include "pytest.h"
> -------------------------------
>
> pytest.h
> -------------------------------
> typedef unsigned char UINT8;
>
> struct outer {
>
>     typedef struct __inner {
>         UINT8 Mode: 2;
>         UINT8 State: 2;
>         UINT8 Fire: 1;
>         UINT8 Spare: 3;
>     } _inner;
>
>     _inner inner;
> };
> -------------------------------
>
> ||=== pytest, Debug ===|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer_inner_set(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|2973|error: `_inner' was not declared in this scope|
> pytest_wrap.cxx|2973|error: expected `;' before "arg2"|
> pytest_wrap.cxx|2995|error: `temp' was not declared in this scope|
> pytest_wrap.cxx|2995|error: `_inner' is not a type|
> pytest_wrap.cxx|2995|error: expected `>' before '*' token|
> pytest_wrap.cxx|2995|error: expected `(' before '*' token|
> pytest_wrap.cxx|2995|error: expected primary-expression before '>'
> token|
> pytest_wrap.cxx|2995|error: expected `)' before ';' token|
> pytest_wrap.cxx|2996|error: `arg2' was not declared in this scope|
> pytest_wrap.cxx|2997|error: type `<type error>' argument given to
> `delete',
> expected pointer|
> pytest_wrap.cxx|2996|warning: unused variable 'arg2'|
> pytest_wrap.cxx|3000|error: `arg2' was not declared in this scope|
> pytest_wrap.cxx|3000|warning: unused variable 'arg2'|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer_inner_get(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|3014|error: `_inner' was not declared in this scope|
> pytest_wrap.cxx|3014|error: expected `;' before "result"|
> pytest_wrap.cxx|3022|error: `result' was not declared in this scope|
> pytest_wrap.cxx|3023|error: `_inner' is not a type|
> pytest_wrap.cxx|3023|error: ISO C++ forbids declaration of `type name'
> with
> no type|
> pytest_wrap.cxx|3023|error: expected `>' before "_inner"|
> pytest_wrap.cxx|3023|error: expected `(' before "_inner"|
> pytest_wrap.cxx|3023|error: expected primary-expression before '>'
> token|
> pytest_wrap.cxx||In function `PyObject*
> _wrap_outer__inner_get(PyObject*,
> PyObject*)':|
> pytest_wrap.cxx|3044|error: invalid use of `outer::_inner'|
> ||=== Build finished: 20 errors, 2 warnings ===|
> --
> View this message in context: http://www.nabble.com/typedef----rename-
> problem-in-struct-tp25931898p25931898.html
> Sent from the swig-user mailing list archive at Nabble.com.
>
>
> -----------------------------------------------------------------------
> -------
> Come build with us! The BlackBerry(R) Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart
> your
> developing skills, take BlackBerry mobile applications to market and
> stay
> ahead of the curve. Join us from November 9 - 12, 2009. Register now!
> http://p.sf.net/sfu/devconference
> _______________________________________________
> Swig-user mailing list
> Swig-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/swig-user

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Swig-user mailing list
Swig-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user

Re: typedef / %rename problem in struct

by David Piepgrass :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 -----Original Message-----
> From: MakaMaka [mailto:xfrost11@...]
> Sent: Tuesday, October 20, 2009 10:35 AM
> To: swig-user@...
> Subject: Re: [Swig-user] typedef / %rename problem in struct
>
>
> Ok, I added the typedef and while it solves the initial problem, it
> creates
> another:
...
> result = (outer__inner *)& ((arg1)->_inner)

Looks like I got the typedef wrong, it should be

%{
#include "pytest.h"
typedef outer::__inner _inner;
%}

But it looks like it still won't work; I really don't know why it's referring to _inner instead of inner. Just guessing: you could also try

%{
#define _inner inner;
%}

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user