关于CoInitializeEx-COINIT_MULTITHREADED使用心得

本文探讨了COM库中CoInitializeEx与CoUninitialize函数在多线程环境下的使用细节,包括不同初始化与释放顺序对主线程和其他子线程的影响,并通过示例代码展示了具体的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CoInitializeEx(NULL, COINIT_MULTITHREADED); 1、在主线程先调用CoInitializeEx,子线程则默认已经初始化,且若子线程调用CoUninitialize,无效,此时主线程仍然保持已初始化的状态,除非主线程调用CoUninitialize; 2、在主线程不调用CoInitializeEx,子线程中调用CoInitializeEx,子线程成功初始化,此时不管子线程是否调用CoUninitialize,其他线程包含主线程都是非初始化状态; 3、在单线程中,CoInitializeEx和CoUninitialize保持成对出现,类似于引用计数机制。

测试代码:

#include <Objbase.h>

#include <windows.h>
#include <shobjidl.h> 
unsigned int CALLBACK thFunc(LPVOID p_param) {
	HRESULT hr2 = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if  (SUCCEEDED(hr2))
	{
		IFileOpenDialog* pFileOpen;
		// Create the FileOpenDialog object.
		hr2 = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
			IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
	}
	//CoUninitialize();

	return 1;
}

unsigned int CALLBACK thFunc2(LPVOID p_param) {
	IFileOpenDialog* pFileOpen;
	// Create the FileOpenDialog object.
	HRESULT hr2 = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
		IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
	CoUninitialize();

	HRESULT hr3 = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
		IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

	return 1;
}

unsigned int CALLBACK thFunc3(LPVOID p_param) {
	HRESULT hr2 = CoInitializeEx(NULL, COINIT_MULTITHREADED);	
	HRESULT hr3 = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	CoUninitialize();
	CoUninitialize();
	if (SUCCEEDED(hr2))
	{
		IFileOpenDialog* pFileOpen;
		// Create the FileOpenDialog object.
		hr2 = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
			IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
	}
	CoUninitialize();

	return 1;
}

int main()
{
	//HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	//CoUninitialize();

	//HANDLE hRepairThread = (HANDLE)_beginthreadex(NULL, 0, thFunc, NULL, 0, NULL);
	HANDLE hRepairThread = (HANDLE)_beginthreadex(NULL, 0, thFunc, NULL, 0, NULL);
	WaitForSingleObject(hRepairThread, INFINITE);
	//HRESULT hr2 = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	//CoUninitialize();
	HANDLE hRepairThread2 = (HANDLE)_beginthreadex(NULL, 0, thFunc3, NULL, 0, NULL);
	WaitForSingleObject(hRepairThread2, INFINITE);


	IFileOpenDialog* pFileOpen;
	// Create the FileOpenDialog object.
	HRESULT hr5 = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
		IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	//CoUninitialize();
	//CoUninitialize();
	if (SUCCEEDED(hr))
	{
		IFileOpenDialog* pFileOpen;
		// Create the FileOpenDialog object.
		hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
			IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

		if (SUCCEEDED(hr))
		{
			// Show the Open dialog box.
			hr = pFileOpen->Show(NULL);

			// Get the file name from the dialog box.
			if (SUCCEEDED(hr))
			{
				IShellItem* pItem;
				hr = pFileOpen->GetResult(&pItem);
				if (SUCCEEDED(hr))
				{
					PWSTR pszFilePath;
					hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

					// Display the file name to the user.
					if (SUCCEEDED(hr))
					{
						MessageBoxW(NULL, pszFilePath, L"File Path", MB_OK);
						CoTaskMemFree(pszFilePath);
					}
					pItem->Release();
				}
			}
			pFileOpen->Release();
		}
		CoUninitialize();
	}

	CoUninitialize();
	if (SUCCEEDED(hr))
	{
		IFileOpenDialog* pFileOpen;
		// Create the FileOpenDialog object.
		hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
			IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

		if (SUCCEEDED(hr))
		{
			// Show the Open dialog box.
			hr = pFileOpen->Show(NULL);

			// Get the file name from the dialog box.
			if (SUCCEEDED(hr))
			{
				IShellItem* pItem;
				hr = pFileOpen->GetResult(&pItem);
				if (SUCCEEDED(hr))
				{
					PWSTR pszFilePath;
					hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

					// Display the file name to the user.
					if (SUCCEEDED(hr))
					{
						MessageBoxW(NULL, pszFilePath, L"File Path", MB_OK);
						CoTaskMemFree(pszFilePath);
					}
					pItem->Release();
				}
			}
			pFileOpen->Release();
		}
		CoUninitialize();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值