error LNK2001 与 RUNTIME_CLASS 的问题解决

在使用RUNTIME_CLASS 时,产生error LNK2001的错误。非常纳闷。

 

检索到一篇文章http://blog.csdn.net/BeyondHaven/archive/2010/11/30/6045461.aspx

error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CQQFace::classCQQFace" 

在用VC做仿QQ面板的时候,加入了几个对话框类,应用RUNTIME_CLASS()时,编译时出现如下错误:

error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CQQFace::classCQQFace"

其中,CQQFace是对话框类名。

解决方法:

在.h文件中加入: DECLARE_DYNCREATE(CQQFace)

对应的,在CPP文件中加入:IMPLEMENT_DYNCREATE(CQQFace, CDialog)

问题解决。

===================================================================

检查文件发现都有上面的代码。

后来,查出是在工程中没有添加头文件和源文件。添加后就编译通过。

===================================================================

其他参考文献http://dev.csdn.net/htmls/15/15754.html

探察RUNTIME_CLASS之类的秘密

学mfc学到文档,视图和框架的时候,知道必须在这三个类的派生类的类声明 
里加上DECLARE_DYNCREATE,然后在类声明外合适的地方加上IMPLEMENT_DYNCREA 
TE,然后文档,视图和框架,还有文档模板就可以协调工作了。查看msdn,发现 
类似的宏有这几对: 
DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 
DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 
DECLARE_SERIAL 和 IMPLEMENT_SERIAL 

虽然msdn里介绍了他们的作用,但对于它们为什么会起这样的作用心里却没 
底,于是翻了翻mfc的源代码,喜欢钻牛角尖的人可以和我一起来钻一钻。 

1。 
RUNTIME_CLASS宏的定义是这样的: 
#define RUNTIME_CLASS(class_name) 
((CRuntimeClass*)(&class_name::class##class_name)) 
其中##的意思是把##两边的符号都进行宏扩展(如果它们是宏的话),然后把扩展 
后的内容连接在一起,中间不加空格。例如:RUNTIME_CLASS(CView)将被扩展成 
: 
(CRuntimeClass*)(&CView::classCView) 
但这个classCView是什么意思?原来,classCView是由DECLARE_DYNAMIC(CView) 
引入的一个public属性的CRuntimeClass类型的静态成员变量: 
static const AFX_DATA CRuntimeClass classCView; 

原来RUNTIME_CLASS的作用就是引用由DECLARE_DYNAMIC宏引入的静态成员变 
量。 

2。DECLARE_DYNAMIC(class_name) 
由于篇幅的原因,宏的具体定义代码就不列出来了,感兴趣的可以去看文件 
afx.h。 
该宏往类中声明了三个成员: 
protected: 
static CRuntimeClass* PASCAL _GetBaseClass(); 
public: 
virtual CRuntimeClass* GetRuntimeClass() const; 
static const AFX_DATA CRuntimeClass class##class_name; 

有两个成员函数,一个静态成员变量class+类名,同RUNTIME_CLASS相似,如 
果是DECLARE_DYNAMIC(CView)的话,这个静态成员变量将是classCView。可见这 
个成员变量的名称是和DECLARE_DYNAMIC的参数有关的。在下文我们把这个成员变 
量统统记做class##class_name。 


这个静态成员和两个成员函数在哪里被初始化和具体实现呢?原来是在IMPL 
EMENT_DYNAMIC宏里。 

3。IMPLEMENT_DYNAMIC(class_name, base_class_name) 
查看它的宏定义,如果_AFXDLL被定义了的话,由DECLARE_DYNAMIC引入的成 
员的初始化和实现是这样的: 

CRuntimeClass* PASCAL class_name::_GetBaseClass() 

return RUNTIME_CLASS(base_class_name); 

CRuntimeClass* class_name::GetRuntimeClass() const 

return RUNTIME_CLASS(class_name); 

AFX_COMDAT const AFX_DATADEF 
CRuntimeClass class_name::class##class_name = 

#class_name, 
sizeof(class class_name), 
0xFFFF, 
NULL, 
NULL, 
&class_name::_GetBaseClass, 
NULL 
};//这是在初始化静态成员变量class##class_name。 
//CRuntimeClass结构的各个成员的意义可查看msdn。 


4。_DECLARE_DYNAMIC(class_name) 
该宏的定义和DECLARE_DYNAMIC(class_name)基本一样。不同之处是静态成员 
class##class_name前面没有const修饰符。 

5。DECLARE_DYNCREATE(class_name) 

该宏也往类中引入了DECLARE_DYNAMIC宏所引入的那三个成员。除此之外,它 
还另外引入了一个成员: 
static CObject* PASCAL CreateObject(); 
该宏引入的成员在IMPLEMENT_DYNCREATE里初始化和实现。 

6。IMPLEMENT_DYNCREATE(class_name, base_class_name) 
该宏自然是初始化和实现由DECLARE_DYNCREATE引入的成员了。 
我们看看CreateObject的实现: 
CObject* PASCAL class_name::CreateObject() 


return new class_name; 

呵,这个函数是如此简单,它就是用CObject类里重载的new操作符创建一个 
该类类型的对象。 

7。_DECLARE_DYNCREATE(class_name) 
该宏引入了和DECLARE_DYNCREATE引入的四个成员差不多的成员。唯一的区别 
是该宏引入的静态成员class##class_name前面没有const修饰符。 

8。DECLARE_SERIAL(class_name) 
该宏引入了和_DECLARE_DYNCREATE所引入的一样的四个成员,另外它还多了 
这么一句: 
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* & 
pOb); 
原来是把重载操作符operator>>的函数当作该类的友元。于是在操作符函数oper 
ator>>中就可以访问该类的成员了。 

9。IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) 
该宏初始化了成员变量: 
CRuntimeClass class_name::class##class_name= 

#class_name, 
sizeof(class class_name), 
wSchema, 
class_name::CreateObject), 
RUNTIME_CLASS(base_class_name), 
NULL 
};//在这里,class##class_name前面是没有const修饰符的。 

该宏还实现了下列函数: 
CObject* PASCAL class_name::CreateObject() 

return new class_name; 


CRuntimeClass* class_name::GetRuntimeClass() const 

return RUNTIME_CLASS(class_name); 


CArchive& AFXAPI operator>> 
(CArchive& ar, class_name* &pOb) 

pOb=(class_name*)ar.ReadObject(RUNTIME_CLASS(class_name)); 
return ar; 


该宏还声明了一个函数原型: 
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: error lnk2001: unresolved external symbol _getpriority 是一个与函数 getpriority 相关的链接错误。该错误表示在链接器阶段无法找到 getpriority 函数的定义。 getpriority 函数是用于获取进程或进程组的优先级的一个标准函数,该函数声明在头文件 #include <sys/resource.h> 中。然而,由于某些原因,链接器无法找到该函数的定义,导致出现 unresolved external symbol 错误。 要解决问题,可以按照以下步骤操作: 1. 确保在源代码中正确地包含了 <sys/resource.h> 头文件。在 C/C++ 源文件的开头添加 #include <sys/resource.h>,以确保查找到正确的函数声明。 2. 检查编译器选项是否正确设置。有时,编译器选项可能需要手动指定以链接相应的库。对于 getpriority 函数,可能需要链接 librt 或 libpthread 库。可以尝试添加 -lrt 或 -lpthread 到编译器的选项中。 3. 确保链接器能够找到 getpriority 函数的实现。实现该函数的库文件应该与编译器链接,以便在链接器阶段解决外部符号引用。这通常涉及到正确设置库文件的路径或将库文件添加到链接器的库路径中。 总结:error lnk2001: unresolved external symbol _getpriority 是一个链接错误,表示编译器无法找到 getpriority 函数的定义。要解决问题,需要确保正确包含头文件、正确设置编译器选项和链接库文件。 ### 回答2: error lnk2001: unresolved external symbol _getpriority是一个链接错误,意味着链接器无法解析对_getpriority的外部符号引用。 _getpriority是一个用于获取进程优先级的函数,它在Windows下没有定义,因此链接器无法找到它的定义。 要解决这个问题,可以采取以下几种方法: 1. 检查代码中是否有对_getpriority函数的调用:首先检查代码中是否存在对_getpriority函数的调用,如果没有必要使用该函数,可以删除相关的代码,这样可以避免链接错误。 2. 更改代码以使用Windows下的类似功能:如果确实需要使用进程优先级相关的功能,可以改用Windows下的类似函数来代替_getpriority。可以使用Windows API中的GetPriorityClass函数来获取进程优先级,该函数返回一个整数值表示进程的优先级类别。 3. 添加相应的库文件:如果你确定代码中需要使用_getpriority函数,可以找到包含该函数定义的库文件,并将其添加到链接器的库文件路径中。可以通过在项目属性中添加相应的附加库路径和库文件名称来实现。 总之,要解决error lnk2001: unresolved external symbol _getpriority链接错误,可以通过删除对_getpriority函数的调用、使用Windows API中的相关函数或添加相应的库文件来解决问题。 ### 回答3: 这个错误是由于在C++代码中使用了一个未解析的外部符号"getpriority"所引起的。"getpriority"是一个用于获取进程优先级的函数,属于POSIX标准库中的一部分。 在C++中,要使用"getpriority"函数,需要包含对应的头文件<sys/resource.h>,并且需要链接实现该函数的库文件。根据错误提示"error lnk2001: unresolved external symbol _getpriority",可以推断出缺少对应的库文件的链接。 解决这个问题可以按照以下步骤进行: 1. 确保正确地包含了头文件<sys/resource.h>: #include <sys/resource.h> 2. 确认编译器的选项是否正确地链接了对应的库文件。 对于使用GCC编译器的情况,需要添加"-l"参数指定链接的库文件名,例如: g++ main.cpp -o main -l库文件名 3. 如果是在Windows平台上开发,可能需要使用Cygwin或MinGW等工具链来编译和链接,以确保POSIX相关的功能可用。 此外,请注意确保包含正确的库文件,并将其放置在正确的位置,以便编译器能够找到并链接到正确的实现。 总之,"error lnk2001: unresolved external symbol _getpriority"错误是由于未能解析所需库文件中的"getpriority"函数引起的。通过检查头文件和链接选项,以及在合适的位置放置正确的库文件,可以解决这个问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值