2013-05-02 15 views
7

私は、下にあるソケット接続が失われた場合に例外を発生させることができる多数のC++関数をラッピングしています。接続を再確立したり、リスト内の他の利用可能なサーバーを試したりするために、「接続を取得する」関数をラップする方法を見つけましたが、try..exceptラッパーを作成して80に提供するソリューションを見つけられません。 + C++関数です。try..catchマクロラッパー同等のcython

#-- client.pxd --- 

cdef extern from "rpc/RpcService.h": 
    cdef cppclass RpcServiceClient: 
     void getProject(ProjectT&, Guid& id) nogil except + 

cdef extern from "client.h": 
    cdef cppclass Client: 
     RpcServiceClient proxy() nogil 

    cdef Client* getClient() nogil except + 


#-- module.pxd --- 

cdef inline Client* conn() except *: 
    # wrap getClient() here with try..except if the 
    # connection was never established 

cpdef inline get_project(Guid& guid): 
    cdef: 
     ProjectT projT # cpp object 
     Project project # cdef python class 

    # this would catch fine in my conn() wrapper 
    # if the connection had never been established 
    # the first time. But if the existing connection 
    # suddenly drops, it will be getProject() that 
    # raises the exception 
    conn().proxy().getProject(projT, guid) 

    project = initProject(projT) 
    return project 

私はtry_call()のようなもので、これらのC++の機能のすべてを包むことができる方法上の任意のヒント?

def try_call(fn, *args, **kwargs): 
    # try fn(*args, **kwargs) and handle 

try_call(conn().proxy().getProject, projT, guid) 

をしかし、明らかに私はPythonオブジェクトとしてこれらのcython機能を渡すことはできません(または多分私はできますか?):これは純粋なPythonがあった場合 は、私は単にこのような何かを行うことができます。

C++で

またはこのような何か:

TRY_CALL_OR_RECONNECT 
conn().proxy().getProject(projT, guid) 
END_TRY_CALL_OR_RECONNECT 
+1

C++や純粋なPythonでこれを行う方法を知っていれば、Cythonでやる必要があるのでしょうか?なぜ、各関数にマクロを貼り付けて、Cythonでラップするか、Python側と同等の機能を果たすCythonコードの周りにPythonラッパーを書く、C++ラッパーを書くのではないでしょうか? – abarnert

+0

ここでは直感を離れますが、サイモン関数をPythonオブジェクトとして渡すことができないような理由はありません。結局のところ、C言語で実装されたライブラリ関数は、Python関数オブジェクトとして渡すこともできます。 – azgult

+0

@abarnert:ラッピングしている元のC++関数を変更することはできません。各呼び出しの周りにこれらのマクロラッパーを配置する場所はC++のどこにありません。私はモジュール全体がcythonであるので、これをcythonでやっています。さもなければ、私はcythonモジュールをインポートする純粋なPythonラッパーを書く必要があり、さらにすべての呼び出しをラップします。 – jdi

答えて

0

あなたは、これが最善のチュートリアルではないかもしれないが、うまくいけば、それは正しい方向にあなたを指すことができますデコレータ

def try_wrapper(x): 
    try: 
     x() 
    except: 
     doSomethingElse() 

@try_wrapper 
def defYouWantToWrap(): 
    doSomething() 

をチェックアウトすることができます

+0

これはPython関数でのみ機能し、C++関数を呼び出すときには機能しません – jdi