一个MFC扩展DLL调用另一个MFC扩展DLL

_Tiny 2015-11-30 12:32:16
RT,我在一个MFC扩展DLL调用另一个MFC扩展DLL中的类,动态创建类对象时出现链接错误,A.DLL和B.DLL同为MFC扩展DLL,均被主程序MDI调用,A也需要调用B,调用代码如下:

context.m_pNewViewClass = RUNTIME_CLASS(CVideoView);
if (!m_wndSplitter1.Create(
&m_wndSplitter, // our parent window is the first splitter
2, 2, // TODO: adjust the number of rows, columns
CSize(10, 10), // TODO: adjust the minimum pane size
&context,
WS_CHILD|WS_VISIBLE|SPLS_DYNAMIC_SPLIT|WS_HSCROLL|WS_VSCROLL,
m_wndSplitter.IdFromRowCol(2, 0)))
{
TRACE("Failed to create the nested dynamic splitter\n");
}


错误如下:
error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CVideoView::classCVideoView" (?classCVideoView@CVideoView@@2UCRuntimeClass@@B)
CVideoView类是B.DLL中显示视频的一个CView子类;在自己创建的MDI应用程序中使用正常,被A.DLL调用时出现上面链接错误。该工程为VC++6.0,经查证确认,是因为A.DLL和B.DLL项目设置预编译选项中均定义了_AFXDLL,_AFXEXT,导致出现此链接错误,但是不知道怎么改。。。
希望那位大神帮忙指导一二,困扰好久了。MFC扩展DLL之间的相互调用需要注意什么问题?先行谢过!
...全文
249 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
信阳毛尖 2015-12-01
  • 打赏
  • 举报
回复
引用 13 楼 CSDNMicrosoftCSDN 的回复:
[quote=引用 12 楼 lsq19871207 的回复:] 不过比较郁闷的是我将这个宏定义到我的B.DLL的stdafx中 ----------------------------------------------------------------------------- 这个宏定义肯定不能放到stdafx中啊,而是要放到dll导出头文件中,毕竟你在外部使用的时候包含的是dll的导出头文件,而不是stdafx.h啊,或者说你的dll导出头文件一般不会包含stdafx.h啊 这样外部当然不知道这个宏是啥意思了。。。。
好的,明白了。谢谢大神耐心指导,还得努力向您学习呀。[/quote] 都是一步步过来的,相互探讨而已
_Tiny 2015-12-01
  • 打赏
  • 举报
回复
引用 12 楼 lsq19871207 的回复:
不过比较郁闷的是我将这个宏定义到我的B.DLL的stdafx中 ----------------------------------------------------------------------------- 这个宏定义肯定不能放到stdafx中啊,而是要放到dll导出头文件中,毕竟你在外部使用的时候包含的是dll的导出头文件,而不是stdafx.h啊,或者说你的dll导出头文件一般不会包含stdafx.h啊 这样外部当然不知道这个宏是啥意思了。。。。
好的,明白了。谢谢大神耐心指导,还得努力向您学习呀。
信阳毛尖 2015-11-30
  • 打赏
  • 举报
回复
先不看其他的,CVideoView类的头文件中加入了DECLARE_DYNCREATE宏了吗?
信阳毛尖 2015-11-30
  • 打赏
  • 举报
回复
不过比较郁闷的是我将这个宏定义到我的B.DLL的stdafx中 ----------------------------------------------------------------------------- 这个宏定义肯定不能放到stdafx中啊,而是要放到dll导出头文件中,毕竟你在外部使用的时候包含的是dll的导出头文件,而不是stdafx.h啊,或者说你的dll导出头文件一般不会包含stdafx.h啊 这样外部当然不知道这个宏是啥意思了。。。。
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
引用 9 楼 lsq19871207 的回复:
[quote=引用 7 楼 CSDNMicrosoftCSDN 的回复:] 在A.DLL项目中,重新定义AFX_CLASS_EXPORT和AFX_CLASS_IMPORT,可以解决这个问题!A.DLL的stdafx中 #ifdef _AFXEXT_PB #define AFX_EXT_CLASS_PB AFX_CLASS_EXPORT #else #define AFX_EXT_CLASS_PB AFX_CLASS_IMPORT #endif 然后A.DLL的导出类加AFX_EXT_CLASS_PB。 但是会有部分类的消息会报错c2491 definition of dllimport static data member not allowed。。。。
是不是应该把B中所有的AFX_CLASS_EXPORT都替换成AFX_EXT_CLASS_PB ? 其实啊,问题你自己也都找到了,A和B同为dll,因此都预定义了_AFXEXT,导致A引用B的是应该是import却变成了export 我觉得你完全不用去用MFC预定义的导入导出控制宏,不就是个导入导出宏控制吗,自己去写嘛,比如在你的B项目头文件中:

#ifdef DLL_B_EXPORTS
#define DLL_B_API __declspec(dllexport)
#else
#define DLL_B_API __declspec(dllimport)
#endif

class DLL_B_API  CVideoView  : public CView
{
     ...//声明
}

DLL_B_API  BOOL XXOO(......);

extern DLL_B_API  long g_lLenth;
然后确保: 1、B项目的‘预处理器”属性中加入 DLL_B_EXPORTS,其他任何项目不能加入该宏 2、DLL_B_API这个名字得唯一的,不要重复 这么一来,不就能控制是expot还是impot了吗? 另外,你仔细想一想,按照你那个解决方法,如果我有一个C DLL也要用B,你是不是还得在C项目中再重写一遍,先不谈麻烦不麻烦,仅耦合性这一点,也太大了些吧?[/quote] 嗯 对的 谢谢 开始按照我说的去改A的预处理设置 改完后C.DLL调用A的时候又要改C的 然后就要改好多好多。。。 确实这样做就没问题了 非常感谢 不过比较郁闷的是我将这个宏定义到我的B.DLL的stdafx中 结果B编译没问题 A编译的时候错误提示B中的每个类都找不到DLL_B_API 实在蛋疼 只能在每个类中声明了一遍 不知道是VC++6.0的问题还是怎么滴。。。
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
谢谢各位回复,结贴散分!
信阳毛尖 2015-11-30
  • 打赏
  • 举报
回复
引用 7 楼 CSDNMicrosoftCSDN 的回复:
在A.DLL项目中,重新定义AFX_CLASS_EXPORT和AFX_CLASS_IMPORT,可以解决这个问题!A.DLL的stdafx中 #ifdef _AFXEXT_PB #define AFX_EXT_CLASS_PB AFX_CLASS_EXPORT #else #define AFX_EXT_CLASS_PB AFX_CLASS_IMPORT #endif 然后A.DLL的导出类加AFX_EXT_CLASS_PB。 但是会有部分类的消息会报错c2491 definition of dllimport static data member not allowed。。。。
是不是应该把B中所有的AFX_CLASS_EXPORT都替换成AFX_EXT_CLASS_PB ? 其实啊,问题你自己也都找到了,A和B同为dll,因此都预定义了_AFXEXT,导致A引用B的是应该是import却变成了export 我觉得你完全不用去用MFC预定义的导入导出控制宏,不就是个导入导出宏控制吗,自己去写嘛,比如在你的B项目头文件中:

#ifdef DLL_B_EXPORTS
#define DLL_B_API __declspec(dllexport)
#else
#define DLL_B_API __declspec(dllimport)
#endif

class DLL_B_API  CVideoView  : public CView
{
     ...//声明
}

DLL_B_API  BOOL XXOO(......);

extern DLL_B_API  long g_lLenth;
然后确保: 1、B项目的‘预处理器”属性中加入 DLL_B_EXPORTS,其他任何项目不能加入该宏 2、DLL_B_API这个名字得唯一的,不要重复 这么一来,不就能控制是expot还是impot了吗? 另外,你仔细想一想,按照你那个解决方法,如果我有一个C DLL也要用B,你是不是还得在C项目中再重写一遍,先不谈麻烦不麻烦,仅耦合性这一点,也太大了些吧?
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
CVideoView类的头文件中加入了DECLARE_DYNCREATE宏,有木有?classCVideoView这个函数一般是由这个宏扩展出来的
则个是有的,DLL中的每个导出类都看过了,不是这个问题。
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
在A.DLL项目中,重新定义AFX_CLASS_EXPORT和AFX_CLASS_IMPORT,可以解决这个问题!A.DLL的stdafx中 #ifdef _AFXEXT_PB #define AFX_EXT_CLASS_PB AFX_CLASS_EXPORT #else #define AFX_EXT_CLASS_PB AFX_CLASS_IMPORT #endif 然后A.DLL的导出类加AFX_EXT_CLASS_PB。 但是会有部分类的消息会报错c2491 definition of dllimport static data member not allowed。。。。
worldy 2015-11-30
  • 打赏
  • 举报
回复
CVideoView类的头文件中加入了DECLARE_DYNCREATE宏,有木有?classCVideoView这个函数一般是由这个宏扩展出来的
worldy 2015-11-30
  • 打赏
  • 举报
回复
那就不应该,被链接库编译时,是不是被什么宏给屏蔽掉了某些函数
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
引用 3 楼 worldy 的回复:
链接选项依赖库中加入被调用dll的.lib文件
为了防止出现这样的错误,在工程设置中链接该库,还在代码中#pragma comment了该库文件!!!
worldy 2015-11-30
  • 打赏
  • 举报
回复
链接选项依赖库中加入被调用dll的.lib文件
_Tiny 2015-11-30
  • 打赏
  • 举报
回复
引用 1 楼 lsq19871207 的回复:
先不看其他的,CVideoView类的头文件中加入了DECLARE_DYNCREATE宏了吗?
DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE都是成对的,没有问题。我新建了一个MDI的工程,测试过我写的B.DLL,是没有问题的!就是在公司项目中调用的时候出现链接问题,而且当且仅当调用B.DLL的工程也为MFC扩展DLL项目时出现这个问题!

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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