none
C#のActiveXコントロールでDISP_E_UNKNOWNLCIDエラー

    質問

  • C#でActiveXを作成して、Tcl/Tkのアプリに埋め込んで使っています。

    単純にDataGridViewのラッパーなのですが、ボタンセルをクリックしたときにTcl側のプロシージャが呼ばれるように、
    C#でイベントを定義したところ、イベントが実行されるところで例外が発生しました。

    System.Runtime.InteropServices.COMException (0x8002000C): 言語が不明です。 (HRESULT からの例外: 0x8002000C (DISP_E_UNKNOWNLCID))

    これを解決するにはどうしたらよいでしょうか?

    どこをあたっても原因が分からず、ここで質問させていただきました。よろしくお願いします。

    詳しくはこちらに書きました。

    http://yyamasak.spaces.live.com/?_c02_vws=1



    環境: WindowsXP Professional SP3
    VS2008 SP1
    .NET Framework 3.5 SP1

    ActiveTcl 8.4.19.1

    2009年9月4日 11:49

回答

  • ざっくり眺めましたが、それは、optclが出しているエラーと思います。

    一般にDISPINTERFACEでのメソッド呼び出しは、GetIDsOfNamesでメソッド名->番号変換を行い、その後Invokeを呼ぶ流れです。
    optclのGetIDsOfNames(EventBinding.cpp:281付近)をC#側から呼び出すわけですが、ココのコードは
    引数lcidがLOCALE_SYSTEM_DEFAULT以外の場合、DISP_E_UNKNOWNLCIDを返す処理になっています。
    この条件に引っかかって、DISP_E_UNKNOWNLCIDが戻り、C#側で例外を発生させているのでしょう。

    そうだとすると、この部分のコードを直さない限りは、C#側からイベントは呼べないことになります。


    jzkey
    • 回答としてマーク yyamasak 2009年9月8日 3:49
    2009年9月7日 13:09

すべての返信

  • ざっくり眺めましたが、それは、optclが出しているエラーと思います。

    一般にDISPINTERFACEでのメソッド呼び出しは、GetIDsOfNamesでメソッド名->番号変換を行い、その後Invokeを呼ぶ流れです。
    optclのGetIDsOfNames(EventBinding.cpp:281付近)をC#側から呼び出すわけですが、ココのコードは
    引数lcidがLOCALE_SYSTEM_DEFAULT以外の場合、DISP_E_UNKNOWNLCIDを返す処理になっています。
    この条件に引っかかって、DISP_E_UNKNOWNLCIDが戻り、C#側で例外を発生させているのでしょう。

    そうだとすると、この部分のコードを直さない限りは、C#側からイベントは呼べないことになります。


    jzkey
    • 回答としてマーク yyamasak 2009年9月8日 3:49
    2009年9月7日 13:09
  • optclの方で起こっていたんですね。
    該当箇所をコメントアウトしてコンパイルしたところ、正常に呼ばれるようになりました。

    optclのソースまで見ていただけるとは思ってませんでした。ありがとうございました。

    lcid 引数に何が渡されているのかとかは調べてないですが、今のところマルチバイト文字はBase64エンコードしたASCII文字列としてやり取りしているので、問題にならないだけかもしれません。存在する以上何かしら弊害はありそうな気はしますが。。。

    今回optclがビルドできるようになったので、マルチバイト関連でいろいろ改善できるようになるかもしれません。
    引き続き、開発を続けたいと思います。

    HRESULT STDMETHODCALLTYPE
    EventBindings::GetIDsOfNames(REFIID riid, LPOLESTR  *rgszNames,
               UINT cNames, LCID lcid, DISPID *rgDispId)
    {
     HRESULT hr = S_OK;
     if (m_pti == NULL)
      hr = DISP_E_UNKNOWNNAME;
    // if (lcid != LOCALE_SYSTEM_DEFAULT)
    //  hr = DISP_E_UNKNOWNLCID;
     else
      hr = DispGetIDsOfNames (m_pti, rgszNames, cNames, rgDispId);
     return hr;
    }

    2009年9月8日 3:46