#68 "beforewrapper" option to %insert

open
nobody
None
5
2014-08-23
2009-04-18
Ben Webb
No

I would like a "beforewrapper" (or some other suitable name) option to %insert.

The rationale: I want to specialize the traits_from class. Since it's a template specialization, it must come after the definition of the template itself. So I can't put this specialization within a %insert(runtime) %{ %} section, because that gets inserted before the template (so does "header"). In fact the only way I can get the code inserted after the template is to use %insert(wrapper). But unfortunately all of the wrapper code is within an extern "C" {} block, and you can't specialize a template within "extern C" code. So currently I have to end the extern C block, write my code, then start a new extern C. This is awkward - it would be easier if I could insert the code after all the runtime stuff but before the wrappers and thus outside the extern C block.

Discussion

  • William Fulton

    William Fulton - 2009-04-18

    Please give a stand-alone example of the problem for us to examine as there is likely to be a solution to your problem.

     
  • Ben Webb

    Ben Webb - 2009-04-18

    See attached beforewrapper.tar.gz. This is my current working solution to the problem. My C++ code returns pointers to refcounted objects (Foo*). Thus, when these objects are passed back to Python, I need to increase the reference count and take ownership (SWIG's ref/unref feature works only in the Foo constructor/destructor, not for Foo* return values). I do this by modifying the out typemap for Foo*.

    However, I also use std::vector<Foo*>. Accessing a Foo* via a vector iterator uses swig::from() rather than the out typemap. Thus I must also specialize struct traits_from. For convenience I define a REFCOUNT macro to do both the out typemap and the template specialization for a given class.

    If I build the wrapper with 'make', everything builds successfully on my Linux box. However, note that because I use %insert(wrapper) I need some ugly code to make sure my code is treated as C++ rather than extern C. If I remove both of the #ifdef __cplusplus blocks from refcount.i I get the following compiler error:
    test_wrap.cxx:4826: error: template specialization with C linkage

    This is because the whole wrapper code is wrapped with extern C. So now let's replace that %insert(wrapper) %{ line with
    %insert(runtime) %{
    or
    %insert(header) %{
    or just
    %{
    With any of these, I now get the compiler error
    test_wrap.cxx:2958: error: ‘traits_from’ is not a template
    test_wrap.cxx:2958: error: explicit specialization of non-template ‘swig::traits_from’

    This is because each of these places the code too early in the file, before the definition of the traits_from template itself.

    Now, I *can* make this work if I edit test.i and move the REFCOUNT(Foo); line to the very end of the file. Then the %{ %} block gets inserted after the traits_from template. But I can't do that because then the out typemap isn't applied.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks