質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

1回答

1731閲覧

Win32のタイプライブラリーでインターフェイスのスーパークラスを求めたい

katahiromz

総合スコア186

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/02/20 11:37

編集2021/02/20 12:00

こんにちは。まずはこちらをご覧下さい。

TLB2IDL
https://github.com/katahiromz/tlb2idl

これは現在作成中のWin32のタイプライブラリファイル(*.tlb)をMIDLファイルに変換するプログラムです。開発環境はWindows10とMSYS2とMSVCです。言語はC++/Win32です。

主な処理は、
https://github.com/katahiromz/tlb2idl/blob/main/CTypeLib.hpp
https://github.com/katahiromz/tlb2idl/blob/main/CTypeLib.cpp
の2つで行っていますが、システムにあるstdole2.tlbを処理したところ、

txt

1 [ 2 uuid(7BF80980-BF32-101A-8BBB-00AA00300CAB), 3 helpstring("Picture Object"), 4 hidden 5 ] 6 interface IPicture : ... { 7 [id(0x60010000), propget, {{1,0,0}}] 8 HRESULT Handle([out, retval] OLE_HANDLE* phandle);

のようにスーパークラスを表示することができません(ここではIPictureのスーパークラス)。

CTypeLib.cppCTypeLibFunc::Loadでスーパークラスの情報を取得する方法を教えて下さい。

ITypeInfo::GetDocumentITypeInfo::GetRefTypeOfImplTypeなど、あれこれ試しましたが、結局、スーパークラスを取得する方法は分かりませんでした。ただ、実装型のImplTypeが1個あるのは分かりました。ImplTypeから情報を取得しようとしましたが、難しいようです。

cpp

1HRESULT CTypeLibFunc::Load(ITypeInfo *pTypeInfo, FUNCDESC *pFuncDesc) 2{ 3 m_funckind = pFuncDesc->funckind; 4 m_invkind = pFuncDesc->invkind; 5 m_memid = pFuncDesc->memid; 6 m_cParams = pFuncDesc->cParams; 7 m_cParamsOpt = pFuncDesc->cParamsOpt; 8 m_oVft = pFuncDesc->oVft; 9 m_cScodes = pFuncDesc->cScodes; 10 m_wFuncFlags = pFuncDesc->wFuncFlags; 11 m_callconv = pFuncDesc->callconv; 12 m_typedesc = getStringOfTypeDesc(pTypeInfo, &pFuncDesc->elemdescFunc.tdesc); 13 14 const UINT cNames = 64; 15 UINT cGotNames; 16 BSTR bstrNames[cNames] = { NULL }, bstrHelpString = NULL; 17 DWORD dwHelpContext = 0; 18 19 pTypeInfo->GetNames(pFuncDesc->memid, bstrNames, cNames, &cGotNames); 20 pTypeInfo->GetDocumentation(pFuncDesc->memid, NULL, &bstrHelpString, &dwHelpContext, NULL); 21 22 BSTR bstrDllName = NULL, bstrEntry = NULL; 23 WORD wOrdinal = 0; 24 pTypeInfo->GetDllEntry(pFuncDesc->memid, m_invkind, &bstrDllName, &bstrEntry, &wOrdinal); 25 m_dllname = sz_or_empty(bstrDllName); 26 m_entry = sz_or_empty(bstrEntry); 27 m_wOrdinal = wOrdinal; 28 SysFreeString(bstrDllName); 29 SysFreeString(bstrEntry); 30 31 if (bstrNames[0]) 32 { 33 m_name = sz_or_empty(bstrNames[0]); 34 } 35 36 if (bstrHelpString) 37 { 38 m_helpstring = sz_or_empty(bstrHelpString); 39 SysFreeString(bstrHelpString); 40 } 41 m_dwHelpContext = dwHelpContext; 42 43 m_cParams = pFuncDesc->cParams; 44 m_cParamsOpt = pFuncDesc->cParamsOpt; 45 for (UINT iParam = 0; iParam < (UINT)m_cParams; ++iParam) 46 { 47 std::wstring name; 48 if (iParam + 1 < cGotNames) 49 name = sz_or_empty(bstrNames[iParam + 1]); 50 if (name.empty()) 51 name = getNewIdentifier(); 52 m_param_names.push_back(name); 53 54 auto pElemDesc = &pFuncDesc->lprgelemdescParam[iParam]; 55 56 auto attrs = getStringOfParamDesc(pTypeInfo, &pElemDesc->paramdesc); 57 m_param_attrs.push_back(attrs); 58 59 auto type = getStringOfTypeDesc(pTypeInfo, &pElemDesc->tdesc); 60 m_param_types.push_back(type); 61 } 62 63 if (m_cParamsOpt == 0) 64 { 65 ; 66 } 67 else if (m_cParamsOpt == -1) 68 { 69 m_param_names.push_back(L""); 70 m_param_attrs.push_back(L""); 71 m_param_types.push_back(L"..."); 72 } 73 74 if (m_invkind == INVOKE_PROPERTYGET) 75 { 76 if (m_typedesc != L"HRESULT") 77 { 78 m_param_attrs.insert(m_param_attrs.end(), L"[out, retval]"); 79 m_param_types.insert(m_param_types.end(), m_typedesc + L"*"); 80 m_param_names.insert(m_param_names.end(), getNewIdentifier()); 81 m_typedesc = L"HRESULT"; 82 } 83 } 84 if (m_typeflags & TYPEFLAG_FOLEAUTOMATION) 85 { 86 if (m_typedesc == L"VOID") 87 { 88 m_typedesc = L"HRESULT"; 89 } 90 else if (m_typedesc == L"VARIANT" || m_typedesc == L"BSTR") 91 { 92 m_param_attrs.insert(m_param_attrs.end(), L"[out, retval]"); 93 m_param_types.insert(m_param_types.end(), m_typedesc + L"*"); 94 m_param_names.insert(m_param_names.end(), getNewIdentifier()); 95 m_typedesc = L"HRESULT"; 96 } 97 } 98 99 for (auto& bstr : bstrNames) 100 { 101 SysFreeString(bstr); 102 bstr = NULL; 103 } 104 105 ITypeInfo2 *pTypeInfo2 = NULL; 106 pTypeInfo->QueryInterface(IID_ITypeInfo2, (LPVOID *)&pTypeInfo2); 107 if (pTypeInfo2) 108 { 109 m_custom = getStringOfCustomData(NULL, pTypeInfo2, m_iFunc); 110 pTypeInfo2->Release(); 111 } 112 113 return S_OK; 114}

参考資料:
FUNCDESC structure (oaidl.h)
ITypeLib interface (oaidl.h)
ITypeLib2 interface (oaidl.h)
ITypeInfo interface (oaidl.h)
ITypeInfo2 interface (oaidl.h)

どうか、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

radianさん、ありがとうございます。

https://github.com/microsoft/VCSamples/blob/master/VC2010Samples/MFC/ole/oleview/iviewers/tlbodl.cpp#L1021

ITypeInfo::GetRefTypeInfoで取得した情報に対してITypeInfo::GetDocumentationMEMBERID_NILを使うことでインターフェイスのベースインターフェイスが取得できるようです。

これで解決できそうです。ありがとうございました。

【追記】
サンプルを試してみましたが、やはりベースインターフェイスが取得できません。
代わりに次のような出力が得られました:

txt

1mincore\com\oleaut32\typelib\tlibapi.cpp(2279)\OLEAUT32.dll!75CC4B84: (caller: 75CC491B) ReturnHr(1) tid(1c8c) 8002801D ライブラリは登録されていません。 2mincore\com\oleaut32\typelib\tlibapi.cpp(2745)\OLEAUT32.dll!75CF2C76: (caller: 002B4E35) ReturnHr(2) tid(1c8c) 8002801D ライブラリは登録されていません。

8002801Dというのは、TYPE_E_LIBNOTREGISTEREDのようです。何らかの登録処理が必要かもしれません。もしかしたらDLL化が必要かもしれません。

投稿2021/02/21 07:53

編集2021/02/21 12:43
katahiromz

総合スコア186

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問