6

SWIGを使用してC++ライブラリのPHPラッパーを作成していますが、データメンバーとしてテンプレートタイプのインスタンスを持つ構造体を使用するのに問題があります。

次のヘッダーファイルがあるとします。

template <typename>
struct myvector
{
};

struct S
{
    myvector<int> v;
};

myvector<int> foo();
S bar();

およびインターフェースファイル:

%module test
%{
#include "test.hpp"
%}

%include "test.hpp"
%template(IntVec) myvector<int>;

を直接返す関数を使おうとすると、正常に機能しますmyvector

$v1 = test::foo();

ただし、オブジェクトを返す関数を使用して、次Sの型のデータメンバーにアクセスしようとすると、次のようになりますmyvector

$s = test::bar();
$v2 = $s->v;

実行時に次のエラーが発生します。

PHP Fatal error:  Class 'myvectorT_int_t' not found in test.php on line 145

インターフェイスファイルから何かが欠落している可能性がありますが、何がわかりません。誰か助けてもらえますか?

4

1 に答える 1

3

私が理解できる限り、これはSWIGのバグです。他の誰かがすでにそれを実際に報告しています。幸いなことに、PHPを介したシンプルで信頼性の高い回避策がありますclass_alias

%module test
%{
#include "test.h"
%}

%pragma(php) code="
# This code is inserted as a workaround for template bugs with SWIG
class_alias('IntVec', 'myvectorT_int_t');
"

%include "test.h"
%template(IntVec) myvector<int>;

ここでのプラグマは、生成されたPHPファイルの先頭にエイリアスを設定するためのコードを挿入します。

(別の可能な回避策もあります-getter / setter関数を介したパブリックメンバー変数アクセスを使用するのではなく、期待どおりに機能します)

バグレポートには、別の考えられる回避策についても記載されていますが、テンプレートタイプにかなり醜い名前を使用する必要があるため、これには熱心ではありません。


バグの仮定の正当化

のコードには次のものが__get含まれます。

$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
                        return new $c($r);

ここに到達すると、ディレクティブを除いてどちらが正しいか$cが設定されます。myvectorT_int_t%template

生成されたコードにmyvector<int> get()関数を追加すると、次のようになります。S

 $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));
 if (!class_exists($c)) {
     return new IntVec($r);
 }
 return new $c($r);

%template これには、がなくても正しく、実際にであるかどうかを確認するための特別なチェックとして、一般的なコードが含まれていIntVecます。

:にもコメントがありSource/Modules/php.cxxます

// FIXME: Currently we always use call_user_func for __get, so we can
// check and wrap the result.  This is needless if all the properties
// are primitive types.  Also this doesn't handle all the cases which
// a method returning an object does.

最後に、Java用の同じインターフェースファイルによって生成されたコードは正しいです。

于 2012-05-10T20:54:34.633 に答える