'SWIG - C++ to python - enum that has ULL values being converted to 0
I have a legacy C++ code base that I am using SWIG to generate python bindings for. In this code base there are enums all over that have specific values that are then used for binary operations.
A typical header file used looks something like this:
namespace doom
{
class Bar
{
public:
struct FooIdent
{
enum Ident
{
UnknownFoo = 0,
KnownFoo = 1,
MainFoo = 2,
SecondaryFoo = 3
};
};
enum FooPresence
{
Boo = 0x0,
Foo1 = 0x8000000000ULL,
Foo2 = 0x4000000000ULL,
Foo3 = 0x2000000000ULL,
FooWithA1 = 0x1000000000ULL,
FooWithA2 = 0x0800000000ULL,
FooWithA3 = 0x0400000000ULL,
FooWithA4 = 0x0200000000ULL,
FooWithB1 = 0x0100000000ULL,
FooWithB2 = 0x0080000000,
FooWithB3 = 0x0040000000
};
Bar();
void setVesODee( int ves, doom::Bar::FooPresence pr );
void setVesOGoo( int goo, doom::Bar::FooIdent::Ident ide );
int doSomething();
private:
int m_vdee;
int m_vgoo;
};
} // namespace doom
The corresponding .cpp file would then be:
#include "bar.h"
#include <iostream>
namespace doom
{
Bar::Bar()
{
m_vdee = 0;
m_vgoo = 0;
}
void Bar::setVesODee( int ves, doom::Bar::FooPresence pr ) {
m_vdee = static_cast< doom::Bar::FooPresence >( ves | pr );
}
void Bar::setVesOGoo( int goo, doom::Bar::FooIdent::Ident ide ) {
m_vgoo = static_cast< doom::Bar::FooIdent::Ident >( goo | ide );
}
int Bar::doSomething() {
return m_vgoo + m_vdee;
}
} // namespace doom
int main() {
doom::Bar b = doom::Bar();
b.setVesODee(3, doom::Bar::FooWithB2);
b.setVesOGoo(4, doom::Bar::FooIdent::MainFoo);
int c = b.doSomething();
std::cout << c << std::endl;
return 0;
}
The .i file would look something like this:
%feature ("flatnested");
%module bar
%{
#include "bar.h";
%}
%rename("Bar_%s", %$isnested) "";
%include "bar.h"
I build using the following commands:
swig -python -c++ -py3 bar.i
g++ -fPIC -c $(pkg-config --cflags --libs python3) bar.cpp bar_wrap.cxx
g++ -shared -o _bar.so bar.o bar_wrap.o
And I then test the code using:
import bar
for i in dir(bar.Bar_FooIdent):
if i[0].isupper():
print(f'{i} = 0x{getattr(bar.Bar_FooIdent, i):X}')
print()
for i in dir(bar.Bar):
if i[0].isupper():
print(f'{i} = 0x{getattr(bar.Bar, i):X}')
This outputs:
KnownFoo = 0x1
MainFoo = 0x2
SecondaryFoo = 0x3
UnknownFoo = 0x0
Boo = 0x0
Foo1 = 0x0
Foo2 = 0x0
Foo3 = 0x0
FooWithA1 = 0x0
FooWithA2 = 0x0
FooWithA3 = 0x0
FooWithA4 = 0x0
FooWithB1 = 0x0
FooWithB2 = 0x-80000000
FooWithB3 = 0x40000000
It seems to be that SWIG does not convert the ULL literals correctly, and I cannot figure out how to tell SWIG to interpret these as larger types.
I am not very comfortable using SWIG but I have been able to make do for a while now and am able to generate most of the code I need. I searched the documentation and questions online, but I have not been able to make this work. Any pointers for making this conversion happen?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
