如何在C++程序中使用C头
How do I use C Headers in a C++ Program?
我正在Visual Studio 2010中进行一个项目,该项目将生成一个win 32 dll文件。我的例子是C文件,编译和工作都很好。我想从我写的C++函数中加入一些功能,但我遇到了一些困难。
如果我试图将C++函数链接到C程序,它对字符串等一无所知,而且根本不起作用(当然(。
所以我只能把这个例子改成C++程序,然后我就可以使用我的其他文件而不受惩罚。当我尝试这样做时,我会遇到一个链接错误,我不理解,也不确定如何解决。
示例使用供应商提供的标题,其中包括诸如之类的语句
typedef void ( __cdecl *BINDING_PROC_BEVNT)(WORD_T choice, INT_T * pStatus,
I_EVNT_T * pIn, O_EVNT_T * pOut);
在主体代码中,以下是示例:
extern BINDING_PROC_BEVNT b_evnt;
这样你就可以写了
b_evnt(choice, &status, &inpEvent, &outpEvent);
在供应商提供的C文件中,这些文件再次被引用为:
BINDING_PROC_BEVNT b_evnt;
b_evnt = (BINDING_PROC_BEVNT)GetProcAddress(hCNCMod, "bevnt");
我看到的链接器错误是:
错误LNK2001:未解析的外部符号"void(__cdecl*b_evnt
如果我重命名主文件并重新编译为C程序,并省略C++函数,那么一切都会完美编译。即使主文件被处理为C++文件,Intellisense似乎也能识别定义(悬停在上面显示正确的定义(。
此外,我试图将外部"C"添加到几个不同的位置,但在C++文件中似乎没有什么不同,并在C文件中生成了一个编译错误(关于不知道字符串(。
任何见解都将不胜感激,我今天可能只是盯着这个看了太久,没有发现一些明显的东西,也可能是我完全不知道的东西。
谢谢你的帮助!
如果您针对具有C语言绑定的库进行编译,则必须明确告诉C++库的头文件引用的是C对象,而不是C++对象,否则C++名称篡改将阻止正确的链接。通常你可以这样做:
extern "C" {
#include "vendor.h"
}
这将告诉C++编译器,大括号之间的符号是C符号,不应该应用名称篡改。
要包含C++中的C头文件,请执行以下操作:
测试.cpp
extern "C" {
#include "c_header_file.h"
}
听起来上面就是您可能需要做的事情,以便在C++代码中包含供应商头文件。
相关地,使头文件自动为C和C++工作:
c_header_file.h
#ifdef __cplusplus
extern "C" {
#endif
void f(int);
// all declarations go here
#ifdef __cplusplus
}
#endif
并非所有供应商提供的头文件都包含上述__cplusplus
检测,因此您必须像第一个示例中那样手动将它们包装在extern "C"
中。
error LNK2001: unresolved external symbol "void (__cdecl* b_evnt)
(unsigned short,short *,union I_EVNT_T *,union O_EVNT_T *)"
(?b_evnt@@3P6AXGPAFPATI_EVNT_T@@PATO_EVNT_T@@@ZA)
这意味着,找不到C++损坏的变量b_evnt。这是真的,因为它应该是C损坏的(只是一个_前缀(。要解决这个问题,请在为C++进行编译时在头中告诉编译器:
#ifdef __cplusplus
extern "C" BINDING_PROC_BEVNT b_evnt;
#else
extern BINDING_PROC_BEVNT b_evnt;
#endif
如果仅此而已,你就完了。如果你需要更多的符号,你可能想使用Greg的解决方案,但要注意,这也不是一个解决方案。
供应商提供的头文件包含在C++编译单元中,但它们不是为C++准备的。因此,函数的声明是用C++编译器支持重载所需的名称篡改来编译的。
标头需要封装在extern "C" {}
块中,以便让C++编译器知道这些声明使用了C链接。
可能最简单的方法是使用您自己的包装头来完成以下操作:
#ifndef FOO_WRAPPER_H
#define FOO_WRAPPER_H
#if __cplusplus
extern "C" {
#endif
#include "foo.h"
#if __cplusplus
}
#endif
#endif
并包含yiour包装器头,而不是供应商的头-包装器将适用于C或C++编译。
此外,请联系您的库供应商,让他们知道他们应该进行这些更改——库的用户不应该为了使用C++中的库而采取这种变通方法。
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 如何通过cpp程序运行shell脚本
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- IPC使用多个管道和分支进程来运行Python程序
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 基于boost的程序的静态链接——zlib问题
- 程序崩溃并显示"std::out_of_range"错误
- 在C应用程序中运行C++(带有STL)函数
- 使用mongocxx驱动程序时包含头文件问题
- 如何在c++程序中找到函数的地址