我有一個 C 代碼庫,它使用 SWIG 生成 Python 3 介面。
我遇到了一個問題,我無法將enum值轉換為足夠大的型別。這在很好的幫助下得到了解決。
現在我有一個與另一個有關的新問題。當最大值作為引數傳入時,將更enum正值作為引數的方法會拋出一個。OverflowErrorenum
我想知道是否有一種通用的方法可以使用該typemap函式來解決這個問題(就像使用列舉物件的方式一樣)。識別所有將enum常量作為引數的方法。還是我需要in typemap為每種enum型別定義一個?
我嘗試過并且有效的方法是將其包含在.i檔案中:
%include "typemaps.i"
%apply unsigned long long { doom::Bar::FooPresence };
但如果有一種“包羅萬象”的東西,比如型別映射,那就太好了constcode。
重現當前行為所需的代碼:
bar.h
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
bar.cpp
#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;
}
bar.i
%module bar
%feature ("flatnested");
%{
#define SWIG
#include "bar.h"
#define SWIG_PYTHON_STRICT_BYTE_CHAR
%}
%typemap(constcode) int %{
SWIG_Python_SetConstant(d, "$symname", PyLong_FromLongLong(static_cast<long long>($1)));
%}
%rename("Bar_%s", %$isnested) "";
%include "bar.h"
test_bar.py
import bar
b = bar.Bar()
b.setVesODee(10, bar.Bar.Foo1)
build-and-test.sh
#!/bin/bash
set -e
echo "Cleanup..."
rm -rf __pycache__
rm -f _bar.so bar.o bar_wrap.*
echo "Building..."
swig -python -c -py3 -debug-tmsearch 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
echo "Testing..."
python3 test_bar.py
output
Traceback (most recent call last):
File "test_bar.py", line 15, in <module>
b.setVesODee(10, bar.Bar.Foo1)
File "/workspace/ctmp/bar.py", line 83, in setVesODee
return _bar.Bar_setVesODee(self, ves, pr)
OverflowError: in method 'Bar_setVesODee', argument 3 of type 'doom::Bar::FooPresence'
uj5u.com熱心網友回復:
SWIGTYPE是未找到特定型別匹配時的默認型別匹配。您可以使用以下內容應用于所有列舉:
%apply unsigned long long { enum SWIGTYPE };
請參閱SWIG 檔案中的13.3.3 默認型別映射匹配規則。
例子:
測驗.i
%module test
%typemap(constcode) int %{SWIG_Python_SetConstant(d, "$1",PyLong_FromLongLong(static_cast<long long>($1)));%}
%apply unsigned long long { enum SWIGTYPE };
%{
#include <iostream>
%}
%inline %{
enum FooPresence : unsigned long long
{
Foo1 = 0x8000000000ULL,
};
void func(FooPresence x) {
std::cout << std::hex << static_cast<unsigned long long>(x) << std::dec << std::endl;
}
%}
演示:
>>> import test
>>> test.func(test.Foo1)
8000000000
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/444259.html
