在Windows 8中,ctypes不能加载特定的dll的问题

yinkaisheng 发布于 2013/11/28 13:56
阅读 414
收藏 0

我用C++(IDE:VS2010)写了一个dll,dll内部又调用了COM. 再用ctypes来调用这个dll.

在Windows XP和Windows 7中,ctypes能正常加载这个dll并调用dll里的导出函数。

但在Windows 8中ctypes不能加载这个dll, 调用ctypes.cdll.LoadLibrary('TestDll.dll')时,函数不返回,脚本卡在这里不动了。

经过多次测试发现是因为调用COM的问题。如果把调用COM部分的代码去掉,在windows 8中ctypes就能正常调用这个dll。

我的windows 8版本是 6.2.9200.16384

python版本是2.7.5.6

我在bugs.python.org上提了一个bug,还没得到回应。

http://bugs.python.org/issue19790

上面链接里还有测试代码的下载链接。如果谁有Windows 8系统,可以验证下是否有这个问题。

代码大体如下:

// dllmain.cpp :
#include "stdafx.h"
#include <Windows.h>

#include <UIAutomation.h>
IUIAutomation *g_pAutomation = NULL;

#define DLL_EXPORT __declspec(dllexport)

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
			if (NULL == g_pAutomation)
			{
				CoInitialize(NULL);
				HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&g_pAutomation);
			}
			break;
		}
	case DLL_THREAD_ATTACH:
		{
			break;
		}
	case DLL_THREAD_DETACH:
		{
			break;
		}
	case DLL_PROCESS_DETACH:
		{
			if (g_pAutomation)
			{
				g_pAutomation->Release();
				CoUninitialize();
			}
			break;
		}
	}
	return TRUE;
}


#ifdef __cplusplus
extern "C"
{
#endif

	DLL_EXPORT int AddTwoNumber(int a, int b)
	{
		return a + b;
	}

#ifdef __cplusplus
}
#endif

 

 

 

加载中
0
y
yinkaisheng

再补充一下,查了一些资料

http://support.microsoft.com/kb/305723

COM application hangs when you call CoCreateInstance from DllMain

SYMPTOMS
When you call the CoCreateInstance function from the DllMain function, the Component Object Model (COM) application hangs.

CAUSE
CoCreateInstance may start a thread that tries to call the DllMain function of all dynamic-link libraries (DLLs) that exist in the process by passing a DLL_THREAD_ATTACH value. Because the call originates from DllMain, and because DllMain is not a reentrant function, the call to CoCreateInstance never returns.

RESOLUTION
To resolve this problem, do not call CoCreateInstance from DllMain. You can move the call to an initialization function or to any other function that is called later.

STATUS
This behavior is by design.


0
sToa
sToa
DllMain里下断,看ctypes.cdll.LoadLibrary('TestDll.dll')时卡在哪里
0
y
yinkaisheng
CoInitialize(NULL);
cout << "before calling CoCreateInstance" <<endl;
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&g_pAutomation);
cout << "after calling CoCreateInstance" <<endl;

加了两句输出语句,经过测试发现是卡在了调用CoCreateInstance的地方。上面只输出了before calling CoCreateInstance,然后就卡住了。

看来在在Windows 8中,不能在DllMain里调用CoCreateInstance.

在Win XP, 7中试过是可以的。

CoCreateInstance放在DllMain外面调用就解决这个问题了。



返回顶部
顶部