C程序中调用RaiseException,为什么LNK出错

redjade 2006-09-07 12:24:20
用VC写的MFC程序,包含一个C文件,在C文件中调用RaiseException,编译的时候告警:
warning C4013: 'RaiseException' undefined; assuming extern returning int

LNK出错:error LNK2001: unresolved external symbol _RaiseException

已经把kernel32.lib加入到项目中了,如果是在CPP文件中调用就没有问题,为什么C文件不行呢?
请大虾指教
...全文
173 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Arthur_ 2006-09-07
  • 打赏
  • 举报
回复
没事情,帮你找的

LNK 2001:两个模块在编译的时候都采用__stdcall调用约定,但是a.dll使用C语言的语法编译的(C语言方式),所以a.dll的载入库a.lib中MakeFun函数的名字修饰就是“_MakeFun@4”。b包含了a提供的头文件中MakeFun函数声明,但是由于b采用的是C++语言编译,所以MakeFun在b模块中被按照C++的名字修饰规则命名为“?MakeFun@@YGJJ@Z”,编译过程相安无事,链接程序时c++的链接器就到a.lib中去找“?MakeFun@@YGJJ@Z”,但是a.lib中只有“_MakeFun@4”,没有“?MakeFun@@YGJJ@Z”,于是链接器就报告:

error LNK2001: unresolved external symbol ?MakeFun@@YGJJ@Z

解决的方法和简单,就是要让b模块知道这个函数是C语言编译的,extern "C"可以做到这一点。一个采用C语言编译的库应该考虑到使用这个库的程序可能是C++程序(使用C++编译器),所以在设计头文件时应该注意这一点。通常应该这样声明头文件:


#ifdef _cplusplus
extern "C" {
#endif

long MakeFun(long lFun);

#ifdef _cplusplus
}
#endif




这样C++的编译器就知道MakeFun的修饰名是“_MakeFun@4”,就不会有链接错误了。

许多人不明白,为什么我使用的编译器都是VC的编译器还会产生“error LNK2001”错误?其实,VC的编译器会根据源文件的扩展名选择编译方式,如果文件的扩展名是“.C”,编译器会采用C的语法编译,如果扩展名是“.cpp”,编译器会使用C++的语法编译程序,所以,最好的方法就是使用extern "C"。

Arthur_ 2006-09-07
  • 打赏
  • 举报
回复
原因是c和c++编译产生的函数名字不同拉,c++产生的比较复杂,c产生就是一个_+函数名而已

解决方法最好在同文件中加"extern c"
Arthur_ 2006-09-07
  • 打赏
  • 举报
回复
project setting ---> generation code -->选stdcall
hailongchang 2006-09-07
  • 打赏
  • 举报
回复
加入afxwin.h

69,378

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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