代码之家  ›  专栏  ›  技术社区  ›  JBRWilkinson

与拉入进程的所有DLL共享一些信息

  •  1
  • JBRWilkinson  · 技术社区  · 16 年前

    我们有一个企业系统,它有许多进程(exes、services、dcom服务器、com+应用程序、isapi、mmc管理单元),所有这些进程都使用许多com组件。我们最近看到了一些客户部署中的失败,但发现很难解决原因。

    为了跟踪这个问题,我们已经用日志记录语句扩充了整个源代码中出现错误的地方。

    为了识别哪些日志来自哪些进程,C++日志代码(编译成所有组件)使用EXE名称来命名日志。这对某些情况很好,但并非所有-com+应用程序、isapi和mmc管理单元都具有系统exe名称,并且日志以交错方式结束。

    我看见了 this post about shared data sections 这可能会有所帮助,但我不理解的是谁决定共享部分的内容。有没有什么方法可以保证在其他人阅读之前,某个特定的代码片段会写入共享部分?

    还是有更好的解决办法?

    2 回复  |  直到 16 年前
        1
  •  1
  •   snowcrash09    16 年前

    要同步写入共享部分的多个进程,您需要某种IPC,例如Windows事件、互斥体、套接字。每个模块调用 CreateMutex 并传递所有模块共享的固定名称。然后,模块调用waitforsingleobject来等待并声明互斥体-当其中一个获得互斥体时,它可以在其他模块等待时读/写共享部分。完成后,它调用releasemutex让另一个模块运行。

    我个人已经说过了,我会坚持使用日志文件。我猜您的问题是,对于DLL,您的日志文件名是基于父进程的exe名称,而不是基于DLL自己的名称?

    通过存储在dllmain中传递的dll实例句柄,然后将其与getmodulefilename一起使用,可以获得dll自己的名称。注意,如果您将实例句柄保留为空,这也适用于exes。

    // global variable to store DLL handle (or it stays NULL if this is an EXE)
    HINSTANCE hDllHandle=NULL;
    
    BOOLEAN WINAPI DllMain( IN HINSTANCE hInstance, 
         IN DWORD     nReason, 
         IN LPVOID    Reserved )
    {
      hDllHandle = hInstance;
      return TRUE;
    
    }
    
    <snip>
    
    void Log(LPSTR lpszMsg)
    {
        WCHAR szMyModuleName[MAX_PATH]={0};
    
        // if hDllHandle is still NULL (e.g. this is an EXE) it returns the process name
        // if non-NULL, it returns our DLL name
        GetModuleFileName(hDllHandle, szMyModuleName, MAX_PATH);
    
        fprintf(LOGFILE, "[%s] %s\n", szMyModuleName, lpszMsg);
    
         ....<snip>....
    }
    
        2
  •  0
  •   Oleg    16 年前

    在dll(带有rws标志的部分)中使用共享部分并不能真正解决您的主要问题。如果需要共享内存以便在进程之间进行快速通信,则可以使用内存映射文件(请参见 http://msdn.microsoft.com/en-us/library/ms810613.aspx 例如)对共享内存的创建和使用有更多的控制。

    要了解加载DLL的进程的更多信息,您可以另外记录应用程序的命令行。( GetCommandLine() 例如函数)。对于mmc管理单元,您将看到类似“c:\windows\system32\mmc.exe c:\windows\system32\services.msc”或“c:\windows\system32\mmc.exe c:\windows\system32\azman.msc”。

    要查看有关呼叫过程的更多信息,可以 StackWalk64 (见 http://msdn.microsoft.com/en-us/library/ms680650(VS.85).aspx )函数。见 http://stackwalker.codeplex.com/ 或 http://www.codeproject.com/KB/threads/StackWalker.aspx 为了一个好的代码示例。