高手进来看看:mfc share dll下正常(全部), static dll下失败(release),出现 CInvalidArgException 异常

muzizongheng
博客专家认证
2009-10-13 08:34:38
如题, mfc share dll的话release和debug都正常, mfc static dll的话release下tabctrl创建失败。

调试后发现在tabctrl的create里RegisterWindowClass失败, 具体原因不明白。

...全文
2427 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
cbx_xx 2011-11-29
  • 打赏
  • 举报
回复
谢谢大家,前一段时间差点对特性功能包库没有信心.
wangshao5210 2010-07-09
  • 打赏
  • 举报
回复
我设置了共享动态连接库后,直接就崩溃了。
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
11楼的可以, 牛。

我在.rc文件里加上了
#if !defined(_AFXDLL)
#include "afxribbon.rc" // MFC ribbon and control bar resources
#endif

多谢happyparrot, 感谢ls所有回帖的朋友。

结贴给分。

muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
我试试 ,多谢楼上所有的朋友。

顺便说下, 我的是2008直接生成的。
快乐鹦鹉 2009-10-13
  • 打赏
  • 举报
回复
微软前不久发布了Visual Studio 2008 Service Pack 1,其中包含了据说是有BCGSoft提供的一些新类,可以直接使用Office 2007/Visual Studio 2005的界面,闻之大喜,终于不用再眼馋BCGControlBar和Xtreme Toolkit这些付费的库了,为了获得VC6的界面,俺还在用自己4年前写的库:)

花了半天时间把手上的工程由VC6迁移到了VC2008,使用动态链接到MFC,一切正常(可惜在中文环境下字体很难看,这个貌似是一个BCG Library的bug,回头等有空再来解决它)。考虑到客户机上可能没有MFC 9.0的DLL,于是改成了静态链接,可惜编译链接没问题,运行时却出错了。

出错的位置位于AfxTabCtrl.cpp第1395行,一个ENSURE宏断言错误,看上去是找不到一个字符串资源。这种错误最为头疼,仔细检查了compiler和linker的设置,使用的库版本,没有发现错误,只好使用土办法“最小系统法”,用VC6生成一个MDI工程,转换到VC2008,加入一个CDockablePane派生的窗口,使用静态链接……果然同样的错误,接着生成了一个空的VS2005 like的空项目,然后从代码入手,一一对比检查,还是没有找到错误的地方,到底问题出在哪呢?忽然想到,或许应该从最原始的地方入手,既然是找不到IDS_AFXBARRES_CLOSEBAR定义的字符串,那么就找找看它在哪定义的,在atlmfc目录下搜索,这个ID定义在afxribbonres.h而存放于afxribbon.rc中。原来问题就在工程的rc文件中。VC2008生成的工程,在其rc文件中有如下代码:

#if !defined(_AFXDLL)
#include "afxribbon.rc" // MFC ribbon and control bar resources
#endif
说明在静态链接的时候,应该手动包含此资源。VC6生成的rc文件中自然是没有这一动作的了,于是打开rc文件,加上这一段代码,顺利通过。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/codewarrior/archive/2008/09/10/2911016.aspx
快乐鹦鹉 2009-10-13
  • 打赏
  • 举报
回复
这个IDS是系统自带的吧。但可能你没有包含这个串所在的资源文件
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
现在是绕开了, 但是为什么呢、 请高手解答

(str.LoadString(IDS_AFXBARRES_CLOSEBAR)); 出错
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
调试了继续, 发现:

int CMFCTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMFCBaseTabCtrl::OnCreate(lpCreateStruct) == -1)
return -1;

CRect rectDummy(0, 0, 0, 0);

if (m_bScroll)
{
//-----------------------
// Create scroll buttons:
//-----------------------
if (m_bFlat)
{
m_btnScrollFirst.Create(_T(""), WS_CHILD | WS_VISIBLE, rectDummy, this, (UINT) -1);
m_btnScrollFirst.SetStdImage(CMenuImages::IdArrowFirst);
m_btnScrollFirst.m_bDrawFocus = FALSE;
m_btnScrollFirst.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;
m_lstButtons.AddTail(m_btnScrollFirst.GetSafeHwnd());
}

m_btnScrollLeft.Create(_T(""), WS_CHILD | WS_VISIBLE, rectDummy, this, (UINT) -1);
m_btnScrollLeft.SetStdImage(m_bFlat ? CMenuImages::IdArrowLeftLarge : CMenuImages::IdArrowLeftTab3d,
m_bIsOneNoteStyle || m_bIsVS2005Style || m_bFlat ? CMenuImages::ImageBlack : CMenuImages::ImageDkGray,
m_bFlat ?(CMenuImages::IMAGES_IDS) 0 : CMenuImages::IdArrowLeftDsbldTab3d);
m_btnScrollLeft.m_bDrawFocus = FALSE;
m_btnScrollLeft.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;

if (!m_bIsOneNoteStyle && !m_bIsVS2005Style)
{
m_btnScrollLeft.SetAutorepeatMode(50);
}

m_lstButtons.AddTail(m_btnScrollLeft.GetSafeHwnd());

m_btnScrollRight.Create(_T(""), WS_CHILD | WS_VISIBLE, rectDummy, this, (UINT) -1);
m_btnScrollRight.SetStdImage( m_bFlat ? CMenuImages::IdArrowRightLarge : CMenuImages::IdArrowRightTab3d,
m_bIsOneNoteStyle || m_bIsVS2005Style || m_bFlat ? CMenuImages::ImageBlack : CMenuImages::ImageDkGray,
m_bFlat ?(CMenuImages::IMAGES_IDS) 0 : CMenuImages::IdArrowRightDsbldTab3d);
m_btnScrollRight.m_bDrawFocus = FALSE;
m_btnScrollRight.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;

if (!m_bIsOneNoteStyle && !m_bIsVS2005Style)
{
m_btnScrollRight.SetAutorepeatMode(50);
}

m_lstButtons.AddTail(m_btnScrollRight.GetSafeHwnd());

if (m_bFlat)
{
m_btnScrollLast.Create(_T(""), WS_CHILD | WS_VISIBLE, rectDummy, this, (UINT) -1);
m_btnScrollLast.SetStdImage(CMenuImages::IdArrowLast);
m_btnScrollLast.m_bDrawFocus = FALSE;
m_btnScrollLast.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;
m_lstButtons.AddTail(m_btnScrollLast.GetSafeHwnd());
}

m_btnClose.Create(_T(""), WS_CHILD | WS_VISIBLE, rectDummy, this, (UINT) -1);
m_btnClose.SetStdImage(CMenuImages::IdClose, m_bIsOneNoteStyle || m_bIsVS2005Style || m_bFlat ? CMenuImages::ImageBlack : CMenuImages::ImageDkGray);
m_btnClose.m_bDrawFocus = FALSE;
m_btnClose.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;
m_lstButtons.AddTail(m_btnClose.GetSafeHwnd());

if (!m_bFlat && m_bScroll)
{
CString str;

//出错 也直接退出函数体
ENSURE(str.LoadString(IDS_AFXBARRES_CLOSEBAR));
m_btnClose.SetTooltip(str);


ENSURE(str.LoadString(IDP_AFXBARRES_SCROLL_LEFT));
m_btnScrollLeft.SetTooltip(str);

ENSURE(str.LoadString(IDP_AFXBARRES_SCROLL_RIGHT));
m_btnScrollRight.SetTooltip(str);
}
}

loadstring也直接出错, 哎, 没法子, 我换了风格, if (m_bScroll)为false。
joimson 2009-10-13
  • 打赏
  • 举报
回复
顶一下
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 happyparrot 的回复:]
m_wndTabCtrl是你自己重写的类对象吧?
[/Quote]

是mfc feature pack的一个控件。

调试到这里错误了 大家看看:


CString AFX_GLOBAL_DATA::RegisterWindowClass(LPCTSTR lpszClassNamePrefix)
{
ENSURE(lpszClassNamePrefix != NULL);

// Register a new window class:
HINSTANCE hInst = AfxGetInstanceHandle();
UINT uiClassStyle = CS_DBLCLKS;
HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW);
HBRUSH hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

//以下是出错代码
CString strClassName;
strClassName.Format(_T("%s:%x:%x:%x:%x"), lpszClassNamePrefix, (UINT_PTR)hInst, uiClassStyle, (UINT_PTR)hCursor, (UINT_PTR)hbrBackground);


// See if the class already exists:
WNDCLASS wndcls;
if (::GetClassInfo(hInst, strClassName, &wndcls))
{
// Already registered, assert everything is good:
ASSERT(wndcls.style == uiClassStyle);
}
else
{
// Otherwise we need to register a new class:
wndcls.style = uiClassStyle;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = hCursor;
wndcls.hbrBackground = hbrBackground;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = strClassName;

if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
}
}

return strClassName;
}
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
这个是 CMFCTabCtrl, 参数没问题的, 要不然编译也通不过。
快乐鹦鹉 2009-10-13
  • 打赏
  • 举报
回复
m_wndTabCtrl是你自己重写的类对象吧?
fishion 2009-10-13
  • 打赏
  • 举报
回复
CTabCtrl 的Create只有四个参数
muzizongheng 2009-10-13
  • 打赏
  • 举报
回复
CRect rectDummy;
rectDummy.SetRectEmpty();

CWnd* pWnd = (CWnd*)GetDlgItem(IDC_TAB1);
if (pWnd != NULL)
{
pWnd->ShowWindow(SW_HIDE);
pWnd->GetWindowRect(&rectDummy);
ScreenToClient(&rectDummy);
}
else
{
return;
}

// Create tabs window:
if (!m_wndTabCtrl.Create(CMFCTabCtrl::STYLE_3D_ONENOTE, rectDummy, this, IDC_TAB1, CMFCTabCtrl::LOCATION_TOP))
{
TRACE0("Failed to create tab window\n");
return; // fail to create
}

程序在static dll下create失败,trace语句都没走到, 直接跳出函数体。出现错误:
First-chance exception at 0x768cfbae in PRRAlarmNotification.exe: Microsoft C++ exception: CInvalidArgException at memory location 0x00159914..
fishion 2009-10-13
  • 打赏
  • 举报
回复
tabctrl你是如何创建的?

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧