【发布时间】:2016-09-03 13:43:15
【问题描述】:
我一直在阅读 COM 和 VBScript,现在我很好奇是否可以使用 CoCreateInstance 函数从 C++ 创建一个 Scripting.Dictionary 对象。
我想要完成的是这样的:
script.vbs
' reminder: run with "cscript script.vbs"
Option Explicit
Dim myDictionary
Set myDictionary = CreateObject("Scripting.Dictionary")
myDictionary.Add "Foo", "Bar"
MsgBox myDictionary.Item("Foo")
我实际上并不了解实例化 COM 对象的过程是如何工作的,但据我了解,它看起来应该是这样的:
main.cpp:
/* reminder: use Unicode */
#include <Windows.h>
#include <stdio.h>
/**
* Takes a guid and dumps it out to stdin as a string.
* @param guid guid to dump to stdin.
*/
void DumpGUID(GUID guid)
{
char dumpData[81];
sprintf_s (
&dumpData[0],
81,
"{"
"\"Data1\": \"%u\","
"\"Data2\": \"%u\","
"\"Data3\": \"%u\","
"\"Data4\": \"%u\""
"}",
guid.Data1,
guid.Data2,
guid.Data3,
guid.Data4
);
puts(dumpData);
}
int main(int argc, char **argv)
{
GUID guid;
const wchar_t *ScriptingDictionaryGUID = L"EE09B103-97E0-11CF-978F-00A02463E06F";
void *myDictionary = NULL;
/* anonymous scope: set guid to 0 so I can tell if it has changed */
{
memset(&guid, 0, sizeof(guid));
}
DumpGUID(guid);
/* anonymous scope: convert my string to guid */
{
HRESULT whyNoConvert = CLSIDFromString((LPCOLESTR)ScriptingDictionaryGUID, &guid);
if (FAILED(whyNoConvert)) {
printf("can't convert string to guid, got error %d.\n", whyNoConvert);
/* ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680589(v=vs.85).aspx */
switch (whyNoConvert) {
case NOERROR:
puts("The CLSID was obtained successfully.");
break;
case CO_E_CLASSSTRING:
puts("The class string was improperly formatted.");
break;
case REGDB_E_CLASSNOTREG:
puts("The CLSID corresponding to the class string was not found in the registry.");
break;
case REGDB_E_READREGDB:
puts("The registry could not be opened for reading.");
break;
}
system("pause");
}
}
DumpGUID(guid);
HRESULT instantiationResult = CoCreateInstance (
guid,
NULL,
CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
IID_IDispatch,
&myDictionary
);
DumpGUID(guid);
if (FAILED(instantiationResult)) {
puts("Can't create a dictionary :(");
} else {
puts("I HAVE DONE IT!");
}
system("pause");
return 0;
}
我的代码无法创建字典对象(但可以编译)... 它也无法从我的字符串实际转换为 GUID,并出现错误“类字符串格式不正确。”。
我不知道我做错了什么(或者我做错了什么)。
编辑:工作代码(仍然需要弄清楚创建对象后如何与对象交互)
#ifndef UNICODE
#define UNICODE
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef STRICT
#define STRICT
#endif
#pragma comment(lib, "uuid.lib")
#pragma comment(lib, "ole32.lib")
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
GUID dictionary_guid = {0xEE09B103, 0x97E0, 0x11CF, {0x97, 0x8F, 0x00, 0xA0, 0x24, 0x63, 0xE0, 0x6F}};
IDispatch* p_dictionary = nullptr;
/* anonymous scope: initializing COM */
{
HRESULT result = CoInitialize(NULL);
if (!SUCCEEDED(result)) {
printf("CoInitialize failed: %u.\n", result);
system("pause");
exit(0);
}
}
/* anonymous scope: creating instance and checking */
{
HRESULT result = CoCreateInstance (
dictionary_guid,
nullptr,
CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
IID_IDispatch,
reinterpret_cast<void**>(&p_dictionary)
);
if (!SUCCEEDED(result)) {
puts("CoCreateInstance failed");
system("pause");
exit(0);
}
puts ("I HAVE DONE IT!");
printf("HRESULT = %u.\n", result);
printf("p_dictionary: %u.\n", p_dictionary);
}
p_dictionary->Release();
CoUninitialize();
system("pause");
return EXIT_FAILURE;
}
提前谢谢!
【问题讨论】:
-
首先你要使用Unicode字符串。
-
我做了更多检查,它说我的 GUID 格式不正确,不知道如何处理。
-
改用
CLSIDFromProgID():CLSIDFromProgID(L"Scripting.Dictionary", &guid); -
字典的属性和方法是documented。使用
IDispatch.Invoke()访问它们。