簡體   English   中英

SWIG C ++ Python構造函數錯誤類型(可能的命名空間問題)

[英]SWIG c++ python constructor wrong type (possible namespace issue)

我有一個完全在頭文件(HKnotVector.h)中實現的類。 我還有一個SWIG接口文件(HKnotVector.i),它定義了一些std_vector.i類型映射。 從另一個文件(common.h)中有HKnotVector.h需要的定義。 如果我將common.h的相關部分復制/粘貼到HKnotVector.i中,則一切運行正常。

當我嘗試在#include "common.h"#include "common.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 > * ,在common.h中,它的typdef d為DoubleVec 當似乎很明顯應該滿足第二個“ C / C ++原型”時,我無法弄清楚為什么將knots傳遞給構造函數會導致此錯誤。

我想強調的是,如果我僅將common.h中的相關代碼復制/粘貼到HKnotVector.i中,則不會收到此錯誤。

我有兩種想法可能會使某人踏上正確的道路:

  1. 當我在.i文件上運行swig時出現錯誤,表明對名稱空間util一無所知,這是DoubleVec在common.h中為typedef d的地方
  2. 我可能需要在某個地方%include common.h ,以便swig知道所有有關它的信息。

編輯(13-11-13)

如果我嘗試在HKnotVector.i中%include "common.h" (恰好在%include "../include/HKnotVector.h"行的上方),則擴展%include "../include/HKnotVector.h"生成而沒有命名空間錯誤( HKnotVector.h:7: Error: Nothing known about namespace 'util' ),但是python無法導入它。 這就是在我用%include "common.h"構建后嘗試運行test.py時發生的情況:

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(13-11-13)

如果我去common.h並刪除指定util命名空間的行,並注釋掉using namespace util; 行在HKnotVector.h中一切正常。

這對我來說很奇怪,因為swig文檔明確指出“對C ++命名空間的支持很全面...”,並且“默認的包裝行為是將目標語言中的命名空間展平。這意味着所有命名空間的內容都合並在一起了在生成的腳本語言模塊中。” 這似乎是我想要的行為,即我希望成為python能夠像使用全局名稱空間一樣從util訪問所有內容。

在這個小示例中,刪除名稱空間規范非常簡單明了。 但是,這只是一個相當大的項目的一小部分,已經對命名空間進行了深入的使用。 盡管我可以編譯該示例,但是刪除名稱空間並不是一個可行的長期解決方案。

正如您所發現的,默認情況下,SWIG處理頭文件時,它不會遞歸到頂級頭文件所包含的頭文件中,因此,您必須%include "common.h"才能將其定義公開給SWIG。

您還發現,在頭文件中使用using語句是一種不好的做法,因為它們將所有內容導入一個名稱空間。 在這種情況下,它會使SWIG混淆。 包括帶有using語句的標頭的任何.cpp文件都必須污染其全局名稱空間。 標頭應尊重名稱空間並完全指定它們,並using語句保留給.cpp文件。

請參閱為什么在C ++中將“使用名稱空間”包含在頭文件中是一個壞主意?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM