如何在C++程序中使用C标头?

Ste*_*hen 5 c c++ function-pointers header-files visual-studio-2010

我正在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);
Run Code Online (Sandbox Code Playgroud)

在主代码的主体中,遵循以下示例:

extern BINDING_PROC_BEVNT       b_evnt;
Run Code Online (Sandbox Code Playgroud)

然后允许你写

b_evnt(choice, &status, &inpEvent, &outpEvent);
Run Code Online (Sandbox Code Playgroud)

在供应商提供的C文件中,这些文件再次引用为:

BINDING_PROC_BEVNT      b_evnt; 
b_evnt = (BINDING_PROC_BEVNT)GetProcAddress(hCNCMod, "bevnt");
Run Code Online (Sandbox Code Playgroud)

我看到的链接器错误是:

错误LNK2001:(?b_evnt @@ 3P6AXGPAFPATI_EVNT_T @@ PATO_EVNT_T @@@ ZA)解析外部符号 "无效(__cdecl*b_evnt)(无符号短,短*,工会I_EVNT_T*,工会O_EVNT_T*)"

如果我重命名我的主文件并重新编译为C程序,并省略我的C++函数,一切都完美编译.即使主文件作为C++文件处理,Intellisense似乎也能识别定义(悬停在上面显示正确的定义).

另外,我试图将extern"C"添加到几个不同的位置,但它似乎没有在C++文件中产生差异,并在C文件中生成编译错误(关于不知道字符串).

任何洞察力都会受到赞赏,我今天可能只是盯着这个太长时间来接受明显的东西,或者它可能是我完全没有意识到的东西.

谢谢您的帮助!

ant*_*oft 10

如果要编译具有C语言绑定的库,则必须明确告诉C++库引用C对象的头文件,而不是C++对象或C++名称修改将阻止正确链接.通常你可以这样做:

extern "C" {
#include "vendor.h"
}
Run Code Online (Sandbox Code Playgroud)

这将告诉C++编译器大括号之间的符号是C符号,并且不应该应用名称修改.

  • 理想情况下,C头供应商会在自己的标头中执行此操作.有些人不这样做太糟糕了.+1. (2认同)

Gre*_*ill 6

要包含C++中的C头文件,请执行以下操作:

TEST.CPP

extern "C" {

#include "c_header_file.h"

}
Run Code Online (Sandbox Code Playgroud)

听起来您可能需要做的就是在C++代码中包含供应商头文件.

相关地,使头文件自动适用于C和C++:

c_header_file.h

#ifdef __cplusplus
extern "C" {
#endif

void f(int);
// all declarations go here

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

并非所有供应商提供的头文件都包含上述__cplusplus检测,因此您必须extern "C"像第一个示例一样手动包装它们.


das*_*ndy 4

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)
Run Code Online (Sandbox Code Playgroud)

这意味着无法找到 C++ 损坏的变量 b_evnt。这是真的,因为它应该被 C 破坏(只是一个 _ 前缀)。要解决这个问题,请在编译 C++ 时在标头中告诉编译器:

#ifdef __cplusplus
extern "C" BINDING_PROC_BEVNT       b_evnt;
#else
extern BINDING_PROC_BEVNT       b_evnt;
#endif
Run Code Online (Sandbox Code Playgroud)

如果仅此而已,那么您就完成了。如果您需要更多符号,您可能想使用 Greg 的解决方案 - 但请注意,这也不是解决所有问题的方法。