- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在阅读 COM 和 VBScript,现在我很好奇是否可以使用 CoCreateInstance 函数从 C++ 创建一个 Scripting.Dictionary 对象。
我想要完成的是这样的:
脚本.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;
}
提前致谢!
最佳答案
如果您使用 Visual Studio,有一个很酷的 #import directive当 Type Library 时生成简化 COM 的包装器可用。
大多数情况下,类型库包含在 COM 对象本身(为您所追求的对象提供服务的 DLL)中,或者包含在 DLL 旁边的 .TLB 中。这是一个简单的示例,其中包含驻留在 C:\Windows\System32\scrrun.dll 中的脚本对象:
#include "stdafx.h"
// import the .TLB that's compiled in scrrun.dll
#import "C:\Windows\System32\scrrun.dll" \
rename("FreeSpace", "FreeSpace2") // avoid name collision with Windows SDK's GetFreeSpace macro, this is specific to scrrun.dll
using namespace Scripting;
// sample usage of Scripting.Dictionary
void CreateDicAndAdd()
{
IDictionaryPtr ptr(__uuidof(Dictionary)); // create an instance of the Dictionary coclass and get an IDictionary pointer back
_variant_t foo = L"foo";
_variant_t bar = L"bar";
ptr->Add(&foo, &bar); // call the Add method
wprintf(L"%i\n", ptr->Count); // call the Count property (wrapper that was generated automatically)
_variant_t outBar;
ptr->get_Item(&foo, &outBar); // get the item for "foo"
// here we know it's a string (outBar.vt could tell you, in case you didn't know)
// in fact, it's a BSTR, but a BSTR is also a LPWSTR
// (the reverse is false, welcome to Automation :-)
wprintf(L"%s\n", outBar.bstrVal);
}
// sample driver code.
int main()
{
CoInitialize(NULL);
CreateDicAndAdd();
CoUninitialize();
return 0;
}
很棒的是所有这些包装器(_variant_t、IDictionaryPtr 等)都很智能,这意味着您不必显式释放或处置它们。最后,它与使用高级语言(VBScript、JScript、C# 等)编写 COM 的方式非常相似。
关于c++ - 如何使用 CoCreateInstance 实例化 Scripting.Dictionary?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39307575/
以下是简短的重现样本: DWORD WINAPI _threadTest (LPVOID) { Sleep (2000); CoInitialize(0); CoCreateI
我是 .NET 程序员和 COM 新手。想简单了解一下 CoCreateInstance 的作用是什么? 最佳答案 你可以想到CoCreateInstance()作为匿名工厂类的接口(interfac
我有一个调用 CoCreateInstance 的函数。此函数被多次调用并且有效,但是有一次 CoCreateInstance 因“变量类型错误”错误而失败。问题是参数在成功和失败时始终相同。什么会导
我尝试用 direct2d 制作位图。问题是 CoCreateInstance(...) 函数不起作用 HRESULT Renderer::InitImagingFactory() { if
我正在使用开源库 EasyHook . 我想做的是,当 VB6 应用程序在特定 CLSID 上从 ole32.dll 调用 CoCreateInstance 时 Hook ,返回我自己的对象 C# 实
我有一个 DLL,我需要在其中调用 CoCreateInstance()。在 Dllmain() 中,我创建了一个新线程来运行我的函数 do_stuff()。 CoCreateInstance() 在
我有一个 Windows 服务,它在初始化期间调用多个 COM+。在某些系统上,此 Windows 服务会在启动期间导致死锁。 At least one service or driver faile
使用 COM 你使用 CoCreateInstance创建一个对象。 有没有办法完全破坏它,以便单元测试的下一部分可以重新开始? 最佳答案 每个持有引用的 COM 接口(interface)指针的人都
我正在尝试使用 Windows 核心音频 API 从麦克风捕获音频 相关的代码行是 const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEn
我正在将一段代码从 C++ 转换为 C#,但不确定如何使用 CoCreateInstance()。这是 C++(这有效并且是我在 C# 中想要的): IComDevice *Device=NULL;
我在这里尝试做的只是创建一个接口(interface)的实例。真的应该这么简单。一直在关注任何在线资料,阅读我能找到但终生无法解决这个问题的资料。 它归结为从 CoCreateInstance 返回的
我有一个关于 CoCreateInstnace() 方法如何定位和创建包含在 COM DLL 中的 CoClass 实例的问题。 根据MSDN : The CoCreateInstance funct
我使用C++ MFC activex脚本调用javascript函数,它编译正常但使用 init 函数运行到 CoCreateInstance,导致读取访问冲突(此 0x4)。如何解决这个问题? 下面
我正在使用 COM 通过 C++ 非托管代码初始化 C# .NET 类,并且即使在非常基本的程序中我也检测到内存泄漏: int _tmain(int argc, _TCHAR* argv[]) {
这是创建 COM 对象的代码示例: CComPtr pFilter; auto hr = CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSC
鉴于一些现有代码调用 CoCreateInstance 来创建已注册 COM 对象的实例,是否有一种方法可以重定向这些调用以创建不同的实例? 想法是在同一个进程中(出于测试目的),在不改变原始代码或影
我想使用 DSound Audio Render在我的一个应用程序中,所以我用 CoCreateInstance 加载它.根据my previous question ,如果我没有安装音频硬件,CoC
当我调用 dll 中的 CoCreateInstance() 时,出现错误“不支持此类接口(interface)”。我正在尝试创建 IGroupPolicyObject 的实例。当我通过 exe 运行
我已经成功编译并注册了一个直接显示过滤器。现在我想在我的代码中使用它。但是对 COCreateInstance 的调用返回错误代码 E_NOINTERFACE。 这是我的过滤器的注册码 #inclu
以上是否可行? 我可以这样做吗: IUnknown *punk; punk->QueryInterface(IID_MyInterface, (void**)&m_pMyInterface); 我认为
我是一名优秀的程序员,十分优秀!