ヘッダー ファイル (HKnotVector.h) に完全に実装されているクラスがあります。いくつかの std_vector.i タイプマップを定義する SWIG インターフェイス ファイル (HKnotVector.i) もあります。別のファイル (common.h) から HKnotVector.h が必要とする定義があります。common.h の関連部分を HKnotVector.i にコピー アンド ペーストすると、すべてが完全に機能します。
#include "common.h"
問題は、 HKnotVector.h 内に入ろうとしたときに発生します。SWIG と python は拡張機能をビルドできますが、次の警告が表示されます。HKnotVector.h:7: Error: Nothing known about namespace 'util'
HKnotVector.h の関連部分は次のとおりです。
/* file HKnotVector.h */
#include "common.h"
#include <vector>
#include <iostream>
using namespace std;
using namespace util;
namespace hbs
{
class HKnotVector
{
public:
HKnotVector( uint degree, const DoubleVec &knots )
: mDeg( degree ), mKnots( knots )
{
getKVecData( mKnots, mGroups, mReverseGroups, mMultipleCount );
}
// A lot of missing code
protected:
uint mDeg;
DoubleVec mKnots;
IntVec mGroups;
IntVecVec mReverseGroups;
IntVec mMultipleCount;
void getKVecData( const DoubleVec &knots, IntVec &knot_groups,
IntVecVec &reverse_knot_groups, IntVec &multiple_counts ) const
{
// Do cool stuff
}
};
}
common.h の関連部分:
/* file common.h */
#include <iostream>
#include <vector>
typedef unsigned int uint;
using namespace std;
namespace util
{
typedef std::vector< double > DoubleVec;
typedef std::vector< int > IntVec;
typedef std::vector< IntVec > IntVecVec;
// A whole bunch of more stuff
}
HKnotVector.i のすべて:
/* file HKnotVector.i */
%module hbspy
%{
#include "HKnotvector.h"
%}
%include "std_vector.i"
namespace std {
%template(IntVec) vector<int>;
%template(DoubleVec) vector<double>;
%template(IntVecVec) vector<vector<int> >;
}
%include "HKnotvector.h"
最後に、HKnotVector のインスタンスを作成しようとするテスト python ファイルがあります。
import hbspy
# Test HKnotVector
py_knots = [0., 0., 0., .25, .5, .75, 1., 1., 1.]
knots = hbspy.DoubleVec(py_knots)
print('knots object: %s\n\n\n' % knots)
kv = hbspy.HKnotVector(2, knots)
を使用してコンパイルしswig -c++ -python HKnotVector.i
、拡張機能をビルドしてテスト ファイルを実行すると、次のようになります。
knots object: <hbspy.DoubleVec; proxy of <Swig Object of type 'std::vector< double > *' at 0x100499450> >
Traceback (most recent call last):
File "./doit", line 17, in <module>
execfile('test.py')
File "test.py", line 18, in <module>
kv = hbspy.HKnotVector(2, knots)
File "/Users/spencerlyon2/Research/HBS/hbs/swig/hbspy.py", line 249, in __init__
this = _hbspy.new_HKnotVector(*args)
NotImplementedError: Wrong number or type of arguments for overloaded function 'new_HKnotVector'.
Possible C/C++ prototypes are:
hbs::HKnotVector::HKnotVector()
hbs::HKnotVector::HKnotVector(uint,DoubleVec const &)
hbs::HKnotVector::HKnotVector(hbs::HKnotVector const &)
ノットを印刷すると、タイプが であることがstd::vector < double > *
わかりtypdef
ますDoubleVec
。knots
2 番目の「C/C++ プロトタイプ」を満たす必要があることが明らかな場合に、コンストラクターに渡すとこのエラーが発生する理由がわかりません。
関連するコードを common.h から HKnotVector.i に単純にコピーして貼り付けると、このエラーは発生しないことを強調したいと思います。
誰かが正しい道を歩むきっかけになるかもしれない 2 つの考えがあります。
- .i ファイルでswig を実行すると、名前空間について何も知られていないというエラーが表示されます
util
。DoubleVec
typedef
- 私は(?)
%include common.h
どこかに行く必要があるかもしれないので、swigはそれについてすべて知っています。
編集 (5-11-13)
%include "common.h"
HKnotVector.i (行のすぐ上) で実行しようとすると%include "../include/HKnotVector.h"
、名前空間エラー ( HKnotVector.h:7: Error: Nothing known about namespace 'util'
) なしで拡張機能がビルドされますが、python はそれをインポートできません。でビルドした後に test.py を実行しようとすると、次のようになり%include "common.h"
ます。
Traceback (most recent call last):
File "test.py", line 10, in <module>
import hbspy
File "/Users/spencerlyon2/Research/HBS/hbs/swig/hbspy.py", line 26, in <module>
_hbspy = swig_import_helper()
File "/Users/spencerlyon2/Research/HBS/hbs/swig/hbspy.py", line 22, in swig_import_helper
_mod = imp.load_module('_hbspy', fp, pathname, description)
ImportError: dlopen(/Users/spencerlyon2/Research/HBS/hbs/swig/_hbspy.so, 2): Symbol not found: __ZN4utillsERSoRKNS_4AxisE
Referenced from: /Users/spencerlyon2/Research/HBS/hbs/swig/_hbspy.so
Expected in: dynamic lookup
何__ZN4utillsERSoRKNS_4AxisE
が何かわかりませんが、拡張モジュールまたは SWIG によって定義された内部シンボルであると想定しています。
編集2 (5-11-13)
common.h に移動して、util
名前空間を指定する行を削除し、HKnotVector.h の行をコメント アウトすると、using namespace util;
すべてが機能します。
swig のドキュメントには、「C++ 名前空間のサポートは包括的です...」と「デフォルトのラッピング動作は、ターゲット言語の名前空間を平坦化することです。これは、すべての名前空間の内容が一緒にマージされることを意味します。結果のスクリプト言語モジュールで。」util
それは私が望む動作のようです。つまり、グローバル名前空間にあるかのようにすべてにアクセスできるように Python になりたいと考えています。
この小さな例では、名前空間の指定を削除するのは単純明快です。ただし、これは、既に名前空間を深く使用しているかなり大規模なプロジェクトの一部です。この例をコンパイルしましたが、名前空間を削除することは実行可能な長期的な解決策ではありません。