Hello, COM(C言語) World!

Posted on 5月 7th, 2012 by cx20

COM(C言語)

COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は C言語による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。
ここでは Windows 標準のプログラム部品である Shell.Application(Shell オブジェクト)の呼出しを例としてる。

ソースコード(事前バインディング)

#include <shlobj.h>
 
int main( int argc, char* argv[] )
{
    HRESULT hResult;
    IShellDispatch* pShell;
    VARIANT vRootFolder;
    Folder* pFolder;
 
    CoInitialize( NULL );
 
    CoCreateInstance( &CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&pShell );
 
    VariantInit( &vRootFolder );
    vRootFolder.vt = VT_I4;
    vRootFolder.lVal = ssfWINDOWS;
 
    pShell->lpVtbl->BrowseForFolder( (void*)pShell, 0, L"Hello, COM World!", 0, vRootFolder, &pFolder );
    VariantClear( &vRootFolder );
    if ( pFolder != NULL )
    {
        pFolder->lpVtbl->Release( (void*)pFolder );
    }
    pShell->lpVtbl->Release( (void*)pShell );
 
    CoUninitialize();
 
    return 0;
}

コンパイル方法(Visual C++)

C:¥> cl hello.c /link ole32.lib

ソースコード(実行時バインディング)

#include <ole2.h>
 
int main( int argc, char* argv[] )
{
    CLSID clsid;
    IDispatch* pShell;
    IDispatch* pFolder;
    DISPID dispid;
    OLECHAR* ptName = L"BrowseForFolder";
    DISPPARAMS param = { NULL, NULL, 0, 0 };
    VARIANT varg[4];
    VARIANT vResult;
 
    CoInitialize( NULL );
 
    CLSIDFromProgID(L"Shell.Application", &clsid );
    CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell);
    pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid );
 
    VariantInit( &varg[0] );
    varg[0].vt = VT_I4;
    varg[0].lVal = 36L;  /* ssfWINDOWS */
 
    VariantInit( &varg[1] );
    varg[1].vt = VT_I4;
    varg[1].lVal = 0L;
 
    VariantInit( &varg[2] );
    varg[2].vt = VT_BSTR;
    varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); 
 
    VariantInit( &varg[3] );
    varg[3].vt = VT_I4;
    varg[3].lVal = 0L;
 
    param.cArgs = 4;
    param.rgvarg = varg;
 
    pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &param, &vResult, NULL, NULL );
 
    VariantInit( &varg[0] );
    VariantInit( &varg[1] );
    VariantInit( &varg[2] );
    VariantInit( &varg[3] );
 
    pFolder = V_DISPATCH( &vResult );
    if ( pFolder != NULL )
    {
        pFolder->lpVtbl->Release( (void*)pFolder );
    }
    pShell->lpVtbl->Release( (void*)pShell );
 
    CoUninitialize();
 
    return 0;
}

コンパイル方法(Visual C++)

C:¥> cl hello.c /link ole32.lib oleaut32.lib

コンパイル方法(MinGW 版 gcc)

C:¥> gcc -o hello hello.c -l ole32 -l oleaut32 -l uuid

実行結果

+----------------------------------------+
|Browse For Folder                    [X]|
+----------------------------------------+
| Hello, COM Wolrd!                      |
|                                        |
| +------------------------------------+ |
| |[Windows]                           | |
| | +[addins]                          | |
| | +[AppCompat]                       | |
| | +[AppPatch]                        | |
| | +[assembly]                        | |
| |     :                              | |
| |     :                              | |
| |     :                              | |
| +------------------------------------+ |
| [Make New Folder]    [  OK  ] [Cancel] |
+----------------------------------------+

Tags:

Categories: COM, C言語, library

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WP-SpamFree by Pole Position Marketing