2010-07-13 84 views
2

一个DLL有以下共享变量(我用MinGW的):仿型的文件句柄

int iCount __attribute__((section(".str"), shared)) = 0; 
HANDLE hMainFile __attribute__((section(".shr"), shared)) = NULL; 
HANDLE hProcess __attribute__((section(".shr"), shared)) = NULL; 

和全局变量:

HANDLE hFile = NULL; 

这是我如何处理我DLL_PROCESS_ATTACH:

case DLL_PROCESS_ATTACH: 
    if(!iCount) 
    { 
    hMainFile = CreateFile("Hello.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    hFile = hMainFile; 
    hProcess = GetCurrentProcess(); 
    iCount = 1; 
    } 
    else 
    { 
    DuplicateHandle(hProcess, hMainFile, GetCurrentProcess(), &hFile, 0, FALSE, DUPLICATE_SAME_ACCESS); 
    } 
    break; 

正如你所看到的,DLL的第一个实例将创建文件和设置共享网络乐手。其余的DLL实例应该将原始文件句柄复制到与其实例兼容的文件句柄。但是,DuplicateHandle总是给出“句柄无效”的错误。我很困惑,因为我不知道它在谈论哪个处理器。我已经确认共享变量在所有实例之间确实是相同的。有人能告诉我我在这里做错了吗?

回答

1

你不能共享这样的句柄。处理共享是Win32比你想象的要严格得多。

要成功分享Win32的一个手柄,你需要做到以下几点:

  • 当调用API打开对象(的CreateFile的文件)传递一个SECURITY_ATTRIBUTES结构,bInheritHandle设置为TRUE。
  • 只有创建了所有可共享对象后,才能使用CreateProcess启动子进程,确保bInheritHandles参数为TRUE。

这将复制子进程中的句柄,以确保重复的句柄具有相同的值。

这只有在您可以遵守第二个进程必须由第一个进程启动并且只有在打开所有潜在共享对象之后才能使用。

但是,在更一般的情况下,进程可能以任何顺序启动,或者需要共享对其他进程启动后打开的对象的访问:在这种情况下,您不能直接共享句柄 - 必须打开在两个进程中通过命名对象 - 显然使用与多次打开的对象兼容的标志。

在CreateFile的情况下:FILE_SHARE_READ | FILE_SHARE_WRITE作为fSharingMode参数将需要打开“Hello.txt”两次。