如何正确使用CoInitialize()和CoInitializeSecurity(),就像我没有调用后者一样,以便可以使用IGlobalOptions? [英] How do I correctly use CoInitialize() and CoInitializeSecurity() as if I didn't call the latter so I can use IGlobalOptions?
问题描述
我的UI在一个调用 CoInitialize()
的DLL中提供,因此我可以使用公共项目对话框,外壳程序打开文件夹对话框。以及可能需要COM的其他任何仅适用于Vista的新产品(我目前尚不知道/不使用任何其他产品)。 DLL还将为自定义控件(过去的问题中我的Table控件,我决定移至UI自动化)提供UI自动化接口。
My UI is provided in a DLL that calls CoInitialize()
so I can use the Common Item Dialog, shell open folder dialog. and any other new Vista-only stuff that may require COM (I don't know of/don't use any others just yet). The DLL will also provide a UI Automation interface to a custom control (my Table control from questions past, which I've decided to move to UI Automation).
我不不想 COM的有用异常处理 ;我希望DLL中的异常能够冒泡进入DLL,以便可以对其进行调试。但是, IGlobalOptions的文档说我需要事先致电 CoInitializeSecurity()
。
I don't want COM's "helpful" exception handling; I want exceptions in my DLL to bubble through to the DLL so they can be debugged. However, the documentation for IGlobalOptions says I need to call CoInitializeSecurity()
beforehand.
我有两个问题:
-
我是否调用
CoInitializeSecurity()
来代替CoInitialize()
?如果除此之外,我应该在调用之前还是之后调用它?
Do I call
CoInitializeSecurity()
instead of or in addition toCoInitialize()
? If in addition to, do I call it before or after?
如果我希望COM像我不调用<那样起作用,那么调用将是什么? code> CoInitializeSecurity()呢?阅读MSDN之后,我知道大多数参数应该是什么,但是我不确定其中的一些参数。
What would the invocation be if I wanted COM to act as if I didn't call CoInitializeSecurity()
at all? After reading MSDN I know what most of the parameters should be, but I'm not sure about some of them.
CoInitializeSecurity(
NULL,
-1, // or is the default 0 instead?
/* can this be NULL? (the error returns table on MSDN implies it can...) if not, what should I specify? */,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
/* what should this be? MSDN says RPC_C_IMP_LEVEL_DEFAULT isn't allowed */,
/* can this be NULL? if not, what should I specify? */,
/* what should this be? MSDN says EOAC_DEFAULT isn't allowed */,
NULL);
或者这在安全性和默认值方面都是完全错误的,还有更好的选择吗?
Or is this completely wrong both security-wise and defaults-wise and there's a better option?
还是我不应该因为这是一个DLL而烦恼吗?
Or should I not even bother doing any of this since this is a DLL?
谢谢。
推荐答案
PS:我假设您的库中不包含实际的 main()
代码。
PS: I'm assuming your library doesn't contain the actual main()
code.
我的UI在调用CoInitialize()的DLL中提供。 ..
My UI is provided in a DLL that calls CoInitialize()...
我希望您在自己的线程中执行此操作,否则会遇到麻烦。
I hope you're doing this in your own thread, otherwise you're asking for trouble.
- 我是否致电CoInitializeSecurity()...
不要在库中执行此操作,而是在整个过程中进行调用,可以由应用程序本身完成,也可以在首次进行跨部门封送处理时执行。
Don't do this in a library, it's a process-wide call, which might be done by the application itself or when cross-apartment marshaling happens for the first time.
- 调用将是...
我会说就是这样(如果未找到注册表信息)。引用:
I'd say this is it, if no registry information is found. To quote:
CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
或者这在安全性和默认值上都是完全错误的,还有更好的选择吗?
Or is this completely wrong both security-wise and defaults-wise and there's a better option?
还有更好的选择。
一个是返回构造的HRESULT并将您的实际错误描述存储在DLL的全局变量之一中,也许使用线程本地存储。
One is to return a constructed HRESULT and store your actual error description in one of your DLL's globals, perhaps using thread-local storage.
如果您使用的是ATL,则可以使用这样的HRESULT并最终使用与您提供给 CComCoClass :: Error
方法的信息相同的信息,您的对象很可能将其用作模板继承。
If you're using ATL, you may use such an HRESULT and end up using the same information you'd feed to your CComCoClass::Error
method, which your objects most probably use as a template inheritance.
或者仅使用ATL的错误处理,就足够了,因为您仍然可以断点自己的代码。
Or just use ATL's error handling, it might be enough since you can breakpoint your own code anyway.
或者因为这是一个DLL,我是否应该不做任何事情?
Or should I not even bother doing any of this since this is a DLL?
这实际上取决于线程所有权。如果您拥有发生这种情况的线程,就可以了;
It actually depends on thread ownership. If you own the thread where this happens, it's OK; if not, it's clearly wrong.
但是请考虑我建议的替代方案。
But consider alternatives like the ones I suggested.
这篇关于如何正确使用CoInitialize()和CoInitializeSecurity(),就像我没有调用后者一样,以便可以使用IGlobalOptions?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!