2015-10-29 2 views
15

私はSWIGのOUTPUTタイプマップをクラスタイプに適用しようとすることにこれまで問題がありましたが、これにはprevious questionと尋ねました。私が得たクラス型のOUTPUTタイプマップを作成するにはどうすればよいですか?

答えはそこに役立ちましたが、まだのような何かを行うにSWIGを頼むために私を必要とします。これは、次のメッセージで、SWIG 3.0.6に私のために動作していないよう

%apply exportedClassType& OUTPUT { exportedClassType& result }; 

を:the documentationを見てから

Warning 453: Can't apply (exportedClassType &OUTPUT). No typemaps are defined.

がprimarことに注意してくださいtypemaps.iファイルの目的は、基本データ型をサポートすることです。 typemaps.iはBarのOUTPUTルールを定義していないので、このような関数を書くことは意図した効果がないかもしれません。 void foo(Bar *OUTPUT);

これはサポートされていないようです。このような、より何かに

// interface.i 
%apply exportedClassType& OUTPUT { exportedClassType& result }; 
int getClassType(exportedClassType& result); 

// interface_wrap.cxx 
SWIGINTERN PyObject *_wrap_getClassType(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { 
    PyObject *resultobj = 0; 
    exportedClassType *arg1 = 0 ; 
    void *argp1 = 0 ; 
    int res1 = 0 ; 
    PyObject * obj0 = 0 ; 
    int result; 

    if (!PyArg_ParseTuple(args,(char *)"O:getClassType",&obj0)) SWIG_fail; 
    res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_exportedClassType, 0); 
    if (!SWIG_IsOK(res1)) { 
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getClassType" "', argument " "1"" of type '" "exportedClassType &""'"); 
    } 
    if (!argp1) { 
    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getClassType" "', argument " "1"" of type '" "exportedClassType &""'"); 
    } 
    arg1 = reinterpret_cast< exportedClassType * >(argp1); 
    result = (int)getClassType(*arg1); 
    resultobj = SWIG_From_int(static_cast<int>(result)); 
    return resultobj; 
fail: 
    return NULL; 
} 

// wrapper.py 
def getClassType(result): 
    return _wrapper.getClassType(result) 
getClassType = _wrapper.getClassType 

:だから私は私の質問は、私はクラスタイプのための生成されたラッパーコードはここから行くようにinterface.iファイルで定義する必要がありますタイプマップのどのような組み合わせで、あると思いますか?

// interface.i 
%apply bool& OUTPUT { bool& result }; 
int getSimpleType(bool& result); 

// interface_wrap.cxx 
SWIGINTERN PyObject *_wrap_getSimpleType(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { 
    PyObject *resultobj = 0; 
    bool *arg1 = 0 ; 
    bool temp1 ; 
    int res1 = SWIG_TMPOBJ ; 
    int result; 

    arg1 = &temp1; 
    if (!PyArg_ParseTuple(args,(char *)":getSimpleType")) SWIG_fail; 
    result = (int)getSimpleType(*arg1); 
    resultobj = SWIG_From_int(static_cast<int>(result)); 
    if (SWIG_IsTmpObj(res1)) { 
    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_bool((*arg1))); 
    } else { 
    int new_flags = SWIG_IsNewObj(res1) ? (SWIG_POINTER_OWN | 0) : 0 ; 
    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg1), SWIGTYPE_p_bool, new_flags)); 
    } 
    return resultobj; 
fail: 
    return NULL; 
} 

// wrapper.py 
def getSimpleType(): 
    return _wrapper.getSimpleType() 
getSimpleType = _wrapper.getSimpleType 

I /アウト/ argoutタイプマップになどSWIG_Python_AppendOutputが私のexportedClassTypeのために呼ばれているので、必要なものを得ることはありません。誰も私にいくつかのポインタを教えてもらえますか?いいえ。

+1

使ってPythonの中からオブジェクトを作成することができます。私は通常、コンストラクタをラップし、SWIGに多態性を処理させますが、出力が参照されるファクトリを作成することができました。 –

+0

[クラスの型にSWIG OUTPUTの型マップを適用する方法は?](http://stackoverflow.com/questions/32478649/how-to-apply-swig-output-typemaps-for-class-types-in) -python) –

答えて

1

inargoutのタイプマップの組み合わせを使用して、望ましい動作を実現できます。私は完全な例が

example.h

#pragma once 
class exportedClassType { 
public: 
    exportedClassType(); 
    ~exportedClassType(); 
}; 
int getClassType(exportedClassType*& result); 

example.cpp以下の通りである次の構文を使用して、それを有効にすることができるようなマクロclass_output_typemapsに一緒に

%class_output_typemaps(exportedClassType) 
%apply (exportedClassType*& ARGOUT_OBJECT) {(exportedClassType *&result)} 

これを入れている

#include "example.h" 
#include <cstdio> 

int getClassType(exportedClassType*& result) { 
    result = new exportedClassType(); 
    return 0; 
} 

exportedClassType::exportedClassType() {printf("ctor\n");} 
exportedClassType::~exportedClassType() {printf("dtor\n");} 

example.i

%module example 
%{ 
    #define SWIG_FILE_WITH_INIT 
    #include "example.h" 
%} 

%include "typemaps.i" 

/* %class_output_typemaps() macro 
* 
* It must be executed for each class CLASS_TYPE, which needs typemaps for output 
*/ 
%define %class_output_typemaps(CLASS_TYPE) 

%typemap(in, numinputs=0) (CLASS_TYPE *&ARGOUT_OBJECT) (CLASS_TYPE* temp) { 
    $1 = &temp; 
} 

%typemap(argout) (CLASS_TYPE *&ARGOUT_OBJECT) { 
    CLASS_TYPE* newObj; 
    *(CLASS_TYPE**)&newObj = *$1; 

    PyObject* temp = NULL; 
    if (!PyList_Check($result)) { 
    temp = $result; 
    $result = PyList_New(1); 
    PyList_SetItem($result, 0, temp); 
    } 

    temp = SWIG_NewPointerObj(SWIG_as_voidptr(newObj), 
       $descriptor(CLASS_TYPE*), 
       SWIG_POINTER_OWN | 0); 

    PyList_Append($result, temp); 
    Py_DECREF(temp); 
} 

%enddef /* %class_output_typemaps() */ 

%class_output_typemaps(exportedClassType) 

%apply (exportedClassType*& ARGOUT_OBJECT) {(exportedClassType *&result)} 

%include "example.h" 

setup.py

#!/usr/bin/env python 
from distutils.core import setup, Extension 
import numpy 
import os 

setup(name='test', 
     version='1.0', 
     ext_modules =[Extension('_example', 
           ['example.i', 'example.cpp'], 
           swig_opts=['-c++'], 
           include_dirs = ['.'])]) 

python setup.py build_ext --inplaceを使用して構築した後、あなたはあなたがエクスポートするメソッドのプロトタイプを提供することができ

import example 
myExportedClassType = example.getClassType()[1] 
関連する問題