自己封装了一个Dll,在调用Dll时出错.
跟踪进去发现是其中在CreateEx()一个CWnd对象时
cs.hInstance = AfxGetInstanceHandle(); 这个地方出了错误,即无法获取全局应
用程序对象的当前实例句柄.
请问各位,这个问题该怎么解决?
谢谢!

解决方案 »

  1.   

    DLL函数里加
    AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
      

  2.   

    AfxGetInstanceHandle always returns the HINSTANCE of your executable file (.EXE) unless it is called from within a DLL linked with the USRDLL version of MFC. In this case, it returns an HINSTANCE to the DLL
      

  3.   

    To: goodboyws(深夜不眠者) 
      我在调用CreateEx()的函数里加了AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
    但问题依旧没有解决.
    To:bohut(●伯虎● /*等待小生命的降临*/)
      那这里应该怎么才能使我CreateEx()一个CWnd成功呢?
      

  4.   

    To:bohut(●伯虎● /*等待小生命的降临*/)
       忘了说明了,你的意思是它得到的是这个Dll的HINSTANCE,但我这里关键问题是,程序执行到AfxGetInstanceHandle()就会报错,根本无法得到任何值
      

  5.   

    class AFX_CLASS_EXPORT CUDPSocketWnd : public CWnd
    {
    public:
    // Construction
    public:
    CUDPSocketWnd();
    CUDPSocket* m_pOwner;protected:
    DECLARE_MESSAGE_MAP()
    afx_msg LRESULT OnDNSLookupDone(WPARAM wParam,LPARAM lParam);};在CUDPSocket中定义了  
            CUDPSocketWnd  m_udpwnd;
    然后
            udpsocket = new CUDPSocket(); // initalize socket for udp packets
            if (!udpsocket->Create()
    其中
    bool CUDPSocket::Create()
    {
       if (thePrefs.GetServerUDPPort())
      {
    // !!!!!!!!出错的地方就在这里!!!!!!!!      
          VERIFY( m_udpwnd.CreateEx(0, _T("0"), _T("eMule Async DNS Resolve Socket Wnd #1"), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL));
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!     
          m_hWndResolveMessage = m_udpwnd.m_hWnd;
          m_udpwnd.m_pOwner = this;
          if (!CAsyncSocket::Create(thePrefs.GetServerUDPPort()==0xFFFF ? 0 : thePrefs.GetServerUDPPort(), SOCK_DGRAM, FD_READ | FD_WRITE))
           {
    return false;
           }
       return true;
      }
      return false;
    }跟踪进去后发现
    BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
    LPCTSTR lpszWindowName, DWORD dwStyle,
    int x, int y, int nWidth, int nHeight,
    HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
    {
    // allow modification of several common create parameters
    CREATESTRUCT cs;
    cs.dwExStyle = dwExStyle;
    cs.lpszClass = lpszClassName;
    cs.lpszName = lpszWindowName;
    cs.style = dwStyle;
    cs.x = x;
    cs.y = y;
    cs.cx = nWidth;
    cs.cy = nHeight;
    cs.hwndParent = hWndParent;
    cs.hMenu = nIDorHMenu; cs.hInstance = AfxGetInstanceHandle();   //就在这个地方出错了
      

  6.   

    不好意思,刚刚的代码有点繁,看起来麻烦.我又做了个实验.
    在我的应用程序中加如下代码,运行正常
    CWnd m_udpwnd;
    m_udpwnd.CreateEx(0, _T("0"), _T("eMule Async DNS Resolve Socket Wnd #1"), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL);
    而一旦将该代码移到Dll的函数中,就出现同样的错误.
    请各位大虾支招了!谢谢
      

  7.   

    有可能在CUDPSocket的构造函数里有内存越界
      

  8.   

    从AfxGetInstanceHandle()跟进去,发现错误在下面的函数中
    inline void* CThreadSlotData::GetThreadValue(int nSlot)
    {
    EnterCriticalSection(&m_sect);
    ASSERT(nSlot != 0 && nSlot < m_nMax);
    ASSERT(m_pSlotData != NULL);
    // 错误在下面这条语句 ,其中nSlot的值是-17891602,错误应该就在这里
    ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED);这应该是什么错误呢?
      

  9.   

    CWnd构造函数的调用也必需先调用模块切换,如果对象的构造不能满足这个,那么可以通过动态创建来解决。P.S. 析构也是如此
      

  10.   

    在nSlot赋值之后,是不是memcpy, strcpy, memset之类的动作
      

  11.   

    对于nSlot,以及GetThreadValue(int nSlot)这个函数,都是MFC内部,在AfxGetInstanceHandle()函数里调用的.我并没有自己的操作
      

  12.   

    我自己写了个class CWndEx::public CWnd类,把CreateEx重载了,在调用AfxGetInstanceHandle()前加了AFX_MANAGE_STATE(AfxGetStaticModuleState( ));但程序错误仍然没有解决.
    我在网上搜了有篇文章讲到,对于Dll,其资源模块如下所讲:
    1. AfxGetResourceHandle、AfxSetResourceHandle、AfxGetInstanceHandle都是针对当前活动模块状态的。AfxGetStaticResourceHandle则是获得当前模块的句柄。2. 实例句柄和资源句柄一般是一样的,但可以改变资源句柄,并不可以改变实例句柄。上文就改变了资源句柄。当使用纯资源dll时,开始就要设置该模块的资源句柄是纯资源DLL的实例句柄(即资源句柄)。
    那么对于实例句柄,真的在Dll中就得不到了吗?
      

  13.   

    用的是MFC扩展DLL吧,我想还是资源句柄的搜索次序问题,在DLL中封装了对话框、窗口等资源后,在DLL外部调用时,会出现无法取得实例句柄的情况。应该在创建对话框、窗口等前用  AfxSetResourceHandle(yourdll.hModule)。