Coinitialize ex 在 JNI 程序存根中的 WMI 调用中失败

Posted

技术标签:

【中文标题】Coinitialize ex 在 JNI 程序存根中的 WMI 调用中失败【英文标题】:Coinitialize ex is failing inside a WMI call in a JNI program stub 【发布时间】:2011-09-07 01:41:14 【问题描述】:

环境:

我有一个由以下部分组成的 JNI 程序

    C++ : 这里我使用 WMI 返回正在运行的进程详细信息。该程序类似于http://msdn.microsoft.com/en-us/library/aa390423(v=vs.85).aspx中的示例 我已经使用 JNI 包装器包含了示例中的整个代码(我发送给程序的参数之一是整数类型)。以下是该函数的签名 JNIEXPORT jdouble JNICALL Java_handlemonitor_NativeSytem_getSystemDetails(JNIEnv *env, jclass cls, jint pId)

生成的DLL保存在JDK目录下的bin文件夹中

    Java:这里我只是调用 dll 中的函数并使用返回值。 我还使用 javah 程序生成 .h 文件,并将其包含在 C++ 程序中。

问题:当我运行程序时,我在 C++ 程序中收到一条错误消息,提示 CoInitializeEx 失败,错误代码为 0x80010106。

下面是程序失败的那一行。

hres = CoInitializeEx(0,COINIT_MULTITHREADED)。

我尝试增加 heapSize 仍然失败。

CoInitializeEx 失败的任何特殊原因?

提前致谢

【问题讨论】:

【参考方案1】:

错误 0x80010106 的意思是“HRESULT - 0x80010106 - 设置后无法更改线程模式。”

问题基本上是线程只能初始化其 COM 模式(和单元类型,STA/MTA)一次。设置后,如果您尝试使用不同的值再次初始化,则会收到此错误。

通常发生此错误的情况是,某些其他 3rd-party 代码会导致 COM 在您的代码执行之前被初始化。如果是这种情况,那么您有两种选择:

1) 尝试找到一种方法让您的代码首先执行,这样您就可以自己设置 COM 单元类型。这可能很棘手,如果第 3 方代码需要 STA,可能会导致副作用

2) 将您的代码放在自己的线程上,您可以在其中显式设置单元类型

如果您实际上并不关心公寓类型,那么您只需更改对 CoInitializeEx 的调用以使用 COINIT_APARTMENTTHREADED (STA) 而不是 COINIT_MULTITHREADED (MTA)。

希望对你有帮助,

约翰

【讨论】:

以上是关于Coinitialize ex 在 JNI 程序存根中的 WMI 调用中失败的主要内容,如果未能解决你的问题,请参考以下文章

Qt-不调用CoInitialize-实现SDL多线程运行

何时调用Windows控制台应用程序所需的CoInitialize

Coinitialize has not been called 错误信息

当一个函数(来自一个库)包含在 VC++ MFC 项目中时,“CoInitialize failed”

win32com.client.Dispatch + Cherrypy = CoInitialize 没有被调用

JNI 异常捕获与处理