Forgive me if this question is silly, but I can't find a good example of %ignore being used around the web. I'm trying to generate a python wrapper for C++ code using the following command:
swig -python -c++ sample.i
I have an interface file like the following:
%module sample
%{
#include <file1.h>
#include <file2.h>
%}
%ignore vprint
%include <file1.h>
%include <file2.h>
%include <file3.h>
I'm trying to exclude the vprint function, defined in file1.h, because it takes in a va_list as a parameter, which SWIG doesn't support the wrapping of. When I include the %ignore statement, I get an error stating "Syntax error in input(1)". Without it, I get the normal error telling me I can't wrap the function I'm trying to ignore. Why might this error be occurring? Thanks in advance!
You certainly need a semicolon after the %ignore:
%ignore vprint;
Related
I am writing C# scripts using Velocity API to automate the clinical trials' time-consuming repetitive procedures.
Velocity API is a library from Varian Medical Systems that was originally written in Python language. It was made available to C# developers through SWIG functions. Unluckily, they did not make a good job. At present, I am stuck with a data type that is not recognized by the C# compiler, namely:
pair <bool, vector>
"pair is a native data type for python and C++ but it is not a recognized data type by the C# compiler.
Through Visual Studio debugger, I browsed through Velocity.dll assembly. I could find the wrapped data type corresponding to the one showed above is:
SWIGTYPE_p_std__pairT_bool_std__vectorT_vsc__VectorR2d_t_t
If I use this latter data type in my C# script, then the C# does not complain. I can get an executable that is useless as I need to get access to the single items of the data pair returned by the method "getStructureHistognam". Unluckily the SWIGTYPE data type does not support any C# method to extract the single items. Nor does it support indexing, as a vector would.
My question for you is:
how can I unravel a variable of type SWIGTYPE_p_std__pairT_bool_std__vectorT_vsc__VectorR2d_t_t
and get access to each one of the two paired data?
SWIG generates opaque pointers for types it doesn't understand. They can be returned and passed to other functions, but not inspected. You would need to modify the SWIG .i source file to recognize the type by either writing appropriate typemaps or including appropriate template instantiations via #include <std_pair.i> and #include <std_vector.i>.
Here's a basic .i file that reveals a std::pair<bool,std::vector<int>> as an example:
%module test
%include <std_pair.i> // SWIG support for std::pair templates
%include <std_vector.i> // SWIG support for std::vector templates
%template(IntVector) std::vector<int>; // Support this template instantiation
%template(BoolIntVectorPair) std::pair<bool,std::vector<int>>; // and this one
%inline %{
#include <utility>
#include <vector>
std::pair<bool,std::vector<int>> get() {
return std::pair<bool,std::vector<int>>{true,{1,2,3}};
}
%}
My C# is rusty but building this file with Python works as shown below. You would use swig -csharp -c++ test.i to generate the wrapper, but I'm using swig -python -c++ test.i here:
>>> import test
>>> test.get()
(True, (1, 2, 3))
I have a C++ library and I use swig to generate Python bindings for it. Many classes have a print function, for them I get a warning like this:
Foo.h:81: Warning 314: 'print' is a python keyword, renaming to '_print'
How can I suppress the warnings? I tried
%ignore print;
But it did not help. Thank you in advance...
I expected that using the warning filtering syntax:
%warnfilter(314) print;
would do the trick, however in this instance it didn't seem to work. I was however able to fix the warning by explicitly doing the rename myself using %rename:
%module test
%rename(_print) print;
void print();
%ignore does also work with SWIG 3.0. Best guess you had the directive and the declaration in the wrong order for example:
%module test
%ignore print;
void print();
Does not warn with 3.0.2
I'm having some issues with SWIG and wchat_t types, to reproduce the issue I got a little MCVE here
The problem is SWIG_AsVal_wchar_t is called but it's not defined anywhere.
I've tried following the accepted answer here but for some reason didn't work for me
How could I solve this?
PS: I've also posted the issue on github
In order to use wchar_t, you could include the interface cwstring.i instead of wchar.i.
This allows to build your sample with this modified libsystem.i :
%module libsystem
%include "cwstring.i"
%{
#include "foo.h"
%}
%include "foo.h"
An other way is to include the missing fragment using the following libsystem.i:
%module libsystem
%include "wchar.i"
%include <typemaps/wstring.swg>
%{
#include "foo.h"
%}
%include "foo.h"
This is very related to this question
Regardless of whether or not this is coding practice, I have come across code that looks like this
test.hh
#include <vector>
using std::vector;
class Test
{
public:
vector<double> data;
};
I am trying to swig this using swig3.0 using the following interface file
test.i
%module test_swig
%include "std_vector.i"
namespace std {
%template(VectorDouble) vector<double>;
};
%{
#include "test.hh"
%}
%naturalvar Test::data;
%include "test.hh"
And the following test code
test.py
t = test.Test()
jprint(t)
a = [1, 2, 3]
t.data = a # fails
doing so gives me the following error
in method 'Test_data_set', argument 2 of type 'vector< double >'
This can be fixed by either changing the using std::vector in test.hh to using namespace std or by removing using std::vector and changing vector<double> to std::vector<double>. This is not what I want.
The problem is that I was given this code as is. I am not allowed to make changes, but I am supposed to still make everything available in python via SWIG. What's going on here?
Thanks in advance.
To me, this looks like SWIG does not support the using std::vector; statement correctly. I think it's a SWIG bug. I can think of the following workarounds:
Add using namespace std; to the SWIG interface file (this will only affect the way wrappers are created; the using statement will not enter C++ code)
Add #define vector std::vector to the SWIG interface file (this will only work if vector is never used as std::vector)
Copy the declarations from the header file to the SWIG interface file, and change vector to std::vector. This will cause SWIG to generate correct wrappers, and again will not affect the C++ library code.
I'm trying to get SWIG to recognize a simple preprocessor macro that "defines" a new function based on another definition and more complicated function. So, in the C header file I have:
#define FOO 1
#define my_macro_fun(args) my_fun(args,FOO)
SWIG sees and successfully wraps my_fun, but I want it to wrap my_macro_fun instead.
SWIG tries to spot macros that are constants and wrap them, but it won't be able to do anything smart with a macro like that. Fortunately there's an easy work around. Imagine you have the following header file:
#define FOO 1
#define my_macro_fun(args) my_fun(args,FOO)
void my_fun(int a, int b);
You can wrap it like:
%module test
%{
#include "test.h"
%}
%include "test.h"
which skips the my_macro_fun function. To get SWIG to wrap that though all you need to do is:
%module test
%{
#include "test.h"
%}
// Lie! Tell SWIG that it should be wrapped like any other function.
void my_macro_fun(int);
// This is entirely optional: it will cause my_fun to be wrapped as well
%include "test.h"
This little lie is perfectly fine in SWIG - it'll generate Wrapper code that assumes my_macro_fun(int) is callable, exactly like you would if you were using the macro. When compiling the wrapper the compiler will end up using the macro there and nobody is any the wiser.
Note that the order is important - the function that's really a macro needs to come before the %include in the interface file otherwise SWIG will try to expand the macro during the parsing of your declaration which makes for a syntax error. You can skip the %include entirely, or use a %ignore as well if you want to include it for other parts but suppress the original my_fun in the generated interface.
With some SWIG languages (e.g. Python) you can also use the typemap default:
%module test
%{
#include "test.h"
%}
%typemap(default) int b {
$1 = FOO;
}
%include "test.h"
To supply a value for an argument if none is given for it.