◀Unicode版開発トップへ
  • 2130 GetDocumentation
    • 2131 Re: GetDocumentation
  • [2130] GetDocumentation anonymous 2014年02月14日 19:42

    掲示板で指摘されているGetDocumentationの問題は
    http://sourceforge.net/p/sakura-editor/patches/152/
    の最後のコメントで答えが出てますが放置されてますね。

    実行確認してないので申し訳ないですが、以下のような感じだと思います。

    virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDocumentation(
    /* [in] */ MEMBERID memid,
    /* [out] */ BSTR __RPC_FAR *pBstrName,
    /* [out] */ BSTR __RPC_FAR *pBstrDocString,
    /* [out] */ DWORD __RPC_FAR *pdwHelpContext,
    /* [out] */ BSTR __RPC_FAR *pBstrHelpFile)
    {
    // Feb. 08, 2004 genta
    // とりあえず全部NULLを返す (情報無し)
    if(pBstrName != NULL) *pBstrName = SysAllocString(m_MethodsRef[memid].Name)
    ; //これでいいのかな?
    //if(pBstrName != NULL) *pBstrName = SysAllocString(L"");
    if(pBstrDocString != NULL) *pBstrDocString = SysAllocString(L"");
    if(pdwHelpContext != NULL) *pdwHelpContext = SysAllocString(L"");
    if(pBstrHelpFile != NULL) *pBstrHelpFile = SysAllocString(L"");
    return S_OK ;
    }

    少なくとも元のpBstrName = NULL;はスタック上の変数を書き換えてるだけです。

    ActiveScriptRubyの呼び出し側は
    https://github.com/arton/RScript20
    のeventsink.cppの111行目あたりです。
    最後のコメントに掲載されてるコードと同じでした。
    • [2131] Re: GetDocumentation もか 2014年02月14日 20:57

      情報ありがとうございます。
      MEMBERID memidは、対応するメソッドID名を返せばいいんですね。

      memid == -1のときに自分の名前を返すようにする必要があるのと、範囲チェックが必要みたいです。
      ちょっとウェブで検索した感じでもRScript20のコードでも、エラーを返す時は呼び出し側のBSTRの後処理が行われないので引数に値を設定してはいけないみたいです。
      もっともRScriptの場合は、サクラ側のGetContainingTypeLibなどが実装されていないので、GetDocumentationまで到達しないと思います。
      もし呼び出し側がBSTRを最初にNULLで初期化しないような実装があった場合は、今の実装だと落ちるかもしれません。
      こんな感じでどうでしょうか。
      m_sNameは、m_MethodsRef同様CIfObjから引っ張ってくるようにしたうえで、
      GetDocumentation(...){
      // 2014.02.12 各パラメータを設定するように
      if( memid == -1 ){
      if( pBstrName ){
      pBstrName = SysAllocString( m_sName.c_str() );
      }
      }else if( 0 <= memid && memid < m_MethodsRef.size() ){
      if( pBstrName ){
      pBstrName = SysAllocString( m_MethodsRef[memid].Name );
      }
      }else{
      return TYPE_E_ELEMENTNOTFOUND;
      }
      if( pBstrDocString ){
      *pBstrDocString = SysAllocString(L"");
      }
      if( pdwHelpContext ){
      *pdwHelpContext = 0;
      }
      if( pBstrHelpFile ){
      *pBstrHelpFile = SysAllocString(L"");
      }
      return S_OK;
      }

      ---
      GetFuncDesc, GetNamesでmemidの範囲チェックをしていないけどいいんだろうか。