I'm have trouble extending/exposing my enum in C++ via SWIG to Python.
I initially created a smaller version of my class "MyClass" without enums and got that working, see below:
SWIG Interface file (MyClassMini.i):
%module MyClassMini
%{
#include "MyClassMini.h"
#include <stdio.h>
#include
#include
using namespace std;
%}
%include "std_string.i"
%include "MyClassMini.h"
Issue commands to auto-generate SWIG wrappers, compile, and link:
swig -python -c++ MyClassMini.i
Compilation & linking:
python setup.py build_ext --inplace
Loading module in a new module into Python, instantiating and setting a string:
Output:
>Python
Type "help", "copyright", "credits" or "license" for more information.
>>> import _MyClassMini
>>> MyClassMini = _MyClassMini.new_MyClassMini();
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Wrong number or type of arguments for overloaded function 'new_MyClassMini'.
Possible C/C++ prototypes are:
MyClassMini::MyClassMini(int)
MyClassMini::MyClassMini(int,int)
MyClassMini::MyClassMini(int,int,int)
MyClassMini::MyClassMini(int,int,int,int)
>>> MyClassMini = _MyClassMini.new_MyClassMini(7);
>>> _MyClassMini.delete_MyClassMini(MyClassMini);
>>> MyClassMini = _MyClassMini.new_MyClassMini(7);
>>> _MyClassMini.MyClassMini_getType(MyClassMini);
7
>>> _MyClassMini.MyClassMini_getType(MyClassMini);
7
>>> _MyClassMini.MyClassMini_setValueString(MyClassMini,"Im a string");
>>> _MyClassMini.MyClassMini_getValueString(MyClassMini);
'Im a string'
>>> _MyClassMini.delete_MyClassMini(MyClassMini);
Everything is working fine.
Enums problem....
I repeated the same SWIG recipe on my actual full-fledged class “MyClass” and the only trouble I had was with enums:
#1 attempt:
MyClass.i:
%module MyClass
%{
#include "MyClass.h"
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include "SparseDataType.h"
using namespace std;
%}
%include "std_string.i"
%include "MyClass.h"
%include "SparseDataType.h"
SWIG interface file SparseDataType.i:
%module SparseDataType
%{
enum SparseDataType
{
SparseBool,
SparseChar,
SparseByte, // unsigned char
SparseInt,
SparseShort,
SparseFloat,
SparseDouble,
SparseString,
SparseComposite
};
%}
Some snippet of MyClass.h:
#ifndef MyClass_H
#define MyClass_H
#include <stdio.h>
#include <iostream>
#include <string.h>
#include "SparseDataType.h"
using namespace std;
class MyClass
{
public:
/*constructors:*/
/*if type is scaler, assume size 1
n is size (if type is scalar, ignore size)*/
MyClass (SparseDataType SparseDataType)
{
size = _n3 = _n2 = _n1= 1;
_type = SparseDataType;
alloc();
}
MyClass (SparseDataType SparseDataType, int size_n1)
{
size = _n1= size_n1;
_n2 = _n3 = 1;
_type = SparseDataType;
alloc();
}
// 2d array
MyClass (SparseDataType SparseDataType, int size_n2 , int size_n1)
{
_n1 = size_n1;
_n2 = size_n2;
_n3 = 1;
size = _n2 * _n1;
_type = SparseDataType;
alloc();
}
// 3d array
MyClass (SparseDataType SparseDataType, int size_n3 , int size_n2, int size_n1)
{
_n3 = size_n3;
_n2 = size_n2;
_n1 = size_n1;
size = _n3 * _n2 * _n1;
_type = SparseDataType;
alloc();
}
//etc…
}
I edited setup.py to include SparseDataType:
from distutils.core import setup, Extension
MyClass_module = Extension('_MyClass',
sources=['MyClass_wrap.cxx'],
)
SparseDataType_module = Extension('_SparseDataType',
sources=['SparseDataType_wrap.cxx'],
)
setup (name = 'MyClass',
version = '0.1',
author = "SWIG Docs",
description = """Simple swig MyClass from docs""",
ext_modules = [MyClass_module,SparseDataType_module],
py_modules = ["MyClass"],
)
**Then I ran SWIG wrapper auto-generation commands again & compilation & linking again:**
swig -python -c++ MyClass.i
swig -python -c++ SparseDataType.i
python setup.py build_ext –inplace
No errors so far, all compiled. Importing into python was fine, but instantiation had problems(enum type is not resolved):
devlinux{user1}% python
Python 2.7.5 (default, Aug 2 2016, 04:20:16)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import _MyClass
>>> import _SparseDataType
>>> MyClass = _MyClass.new_MyClass(_SparseDataType.SparseInt);
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'SparseInt'
Attempt # 2 changed, %module SparseDataType.i (based on Wrapping C-enum in a Python module with Swig ):
%module SparseDataType
%inline %{
struct mySparseDataType {
enum {
SparseBool,
SparseChar,
SparseByte, // unsigned char
SparseInt,
SparseShort,
SparseFloat,
SparseDouble,
SparseString,
SparseComposite
};
};
%}
Then I reran SWIG commands:
swig -python -c++ MyClass.i
swig -python -c++ SparseDataType.i
python setup.py build_ext –inplace
No errors so far, all compiled.
devlinux{user1}% python
>>> import _MyClass
>>> import _SparseDataType
>>> MyClass = _MyClass.new_MyClass(_SparseDataType.mySparseDataType.SparseInt);
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'mySparseDataType'
>>> MyClass = _MyClass.new_MyClass(_SparseDataType.SparseInt); Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'SparseInt'
>>> MyClass = _MyClass.new_MyClass(mySparseDataType.SparseInt); Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'mySparseDataType' is not defined
Again unable to resolve enum "undefined"??
Any ideas on how to call the enum from Python?
Thanks a million!
import SparseDataType
not import _SparseDataType
. The later imports the _SparseDataType.pyd
directly and bypasses the SparseDataType.py
wrapper intended to be imported.
Then, SparseDataType.mySparseDataType.SparseInt
will access the enumeration value. The enum
is inside a structure, so you need module.structure.enum
to access it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.