VC8.0 から System.Collections.ArrayList を操作する
C++/CLI ではなく、VC8.0 から COM 相互運用機能経由で .NET Framework の
System.Collections.ArrayList を操作するコードを書いてみました
IEnumVARIANT::Reset と IEnumVARIANT::Next が S_FALSE を返すので、
このコードでは使用しないようにしています
System.Collections.ArrayList が、IEnumVARIANT を提供していないためという
認識です
■ com_ex.cpp
#include "stdafx.h"
static bool com_invoke(int argc, wchar_t* argv[])
{
try{
if (!argc){
wprintf(L"argc is zero.\n");
return true;
}
// ArrayList
mscorlib::_ArrayListPtr array_list(__uuidof(mscorlib::ArrayList));
// IList
mscorlib::IList* list_obj = NULL;
HRESULT result = array_list->QueryInterface(__uuidof(mscorlib::IList), (void**)&list_obj);
if (S_OK != result){
wprintf(L"mscorlib::ArrayList::QueryInterface fail(IList).\n");
return false;
}
mscorlib::IListPtr list(list_obj);
// IEnumerable
mscorlib::IEnumerable* enumerable_obj = NULL;
result = array_list->QueryInterface(__uuidof(mscorlib::IEnumerable), (void**)&enumerable_obj);
if (S_OK != result){
wprintf(L"mscorlib::ArrayList::QueryInterface fail(IEnumerable).\n");
return false;
}
// IEnumVARIANT
IEnumVARIANT* enum_var = NULL;
result = enumerable_obj->GetEnumerator(&enum_var);
if (S_OK != result){
wprintf(L"mscorlib::IEnumerable::GetEnumerator fail.\n");
enumerable_obj->Release();
enumerable_obj = NULL;
return false;
}
enumerable_obj->Release();
enumerable_obj = NULL;
_COM_SMARTPTR_TYPEDEF(IEnumVARIANT, __uuidof(IEnumVARIANT));
IEnumVARIANTPtr enum_var_obj(enum_var);
// IList::Add
for (int i = 0; argc > i; ++i){
long ret_val = 0;
result = list->Add(_variant_t(argv[i]), &ret_val);
if (S_OK != result){
wprintf(L"IList::Add fail(%ws).\n", argv[i]);
return false;
}
}
// IList::Item
for (int i = 0; argc > i; ++i){
_variant_t value;
result = list->get_Item(i, &value);
if (S_OK != result){
wprintf(L"IList::Item fail(%ws).\n", argv[i]);
return false;
}
wprintf(L"%ws\n", (const wchar_t*)(_bstr_t(value)));
}
}catch (_com_error& e){
wprintf(L"%ws\n", e.ErrorMessage());
return false;
}
return true;
}
int wmain(int argc, wchar_t* argv[])
{
HRESULT result = ::CoInitialize(NULL);
if (S_OK != result){
exit(EXIT_FAILURE);
}
if (com_invoke(argc, argv)){
getchar();
::CoUninitialize();
exit(EXIT_FAILURE);
}
getchar();
::CoUninitialize();
return 0;
}
■ stdafx.h
#pragma once
// 下で指定された定義の前に対象プラットフォームを指定しなければならない場合、以下の定義を変更してください。
// 異なるプラットフォームに対応する値に関する最新情報については、MSDN を参照してください。
#ifndef WINVER // Windows XP 以降のバージョンに固有の機能の使用を許可します。
#define WINVER 0x0501 // これを Windows の他のバージョン向けに適切な値に変更してください。
#endif
#ifndef _WIN32_WINNT // Windows XP 以降のバージョンに固有の機能の使用を許可します。
#define _WIN32_WINNT 0x0501 // これを Windows の他のバージョン向けに適切な値に変更してください。
#endif
#ifndef _WIN32_WINDOWS // Windows 98 以降のバージョンに固有の機能の使用を許可します。
#define _WIN32_WINDOWS 0x0410 // これを Windows Me またはそれ以降のバージョン向けに適切な値に変更してください。
#endif
#ifndef _WIN32_IE // IE 6.0 以降のバージョンに固有の機能の使用を許可します。
#define _WIN32_IE 0x0600 // これを IE. の他のバージョン向けに適切な値に変更してください。
#endif
#define WIN32_LEAN_AND_MEAN // Windows ヘッダーから使用されていない部分を除外します。
#include
#include
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 一部の CString コンストラクタは明示的です。
#include
#include
#include
#include
#import raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") rename("ReportEvent","mscorlib_ReportEvent")
#import raw_interfaces_only high_property_prefixes("_get","_put","_putref")
#import raw_interfaces_only high_property_prefixes("_get","_put","_putref")
#import raw_interfaces_only high_property_prefixes("_get","_put","_putref")
#import raw_interfaces_only high_property_prefixes("_get","_put","_putref")
#import raw_interfaces_only high_property_prefixes("_get","_put","_putref")