Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C++;节目?_C++_C_Visual Studio 2010_Function Pointers_Header Files - Fatal编程技术网

C++ 如何在C++;节目?

C++ 如何在C++;节目?,c++,c,visual-studio-2010,function-pointers,header-files,C++,C,Visual Studio 2010,Function Pointers,Header Files,我正在Visual Studio 2010中进行一个项目,该项目将生成一个win 32 dll文件。我举的例子是C文件和编译程序,它们运行良好。我想把一些功能从C++函数中写出来,但我已经碰到了一点墙。 如果我试图把C++函数链接到C程序,它就不知道字符串,等等,只是根本不起作用。 所以我把这个例子变成C++程序,然后我可以使用我的其他文件,不受惩罚。当我尝试这样做时,我得到一个链接错误,我不明白,也不确定如何解决 示例使用供应商提供的标题,其中包括以下语句 typedef void ( __

我正在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(uu-cdecl*b\u-evnt)(无符号短、短*、并集I\u-evnt\u-T*、并集O\u-evnt\u-T*)”(?b\u-evnt@@3P6AXGPAFPATI\u-evnt\u-T@@PATO\u-evnt\u-T@@@ZA)

< >如果我重命名我的主文件并重新编译为C程序,省略了我的C++函数,一切都会完美地编译。即使主文件被处理为C++文件,智能感知也会识别出定义(悬停在正确的定义上)。

另外,我尝试将外部“C”添加到几个不同的位置,但是它似乎对C++文件没有什么影响,并且在C文件中生成了编译错误(关于不知道字符串)。 任何洞察都是值得赞赏的,我今天可能只是盯着这件事看得太久了,以至于没有意识到一些明显的东西,或者可能是我完全没有意识到的东西


谢谢你的帮助

> P>从C++中包含C头文件,执行如下操作:< /P> test.cpp <>听起来,上面提到的是你需要在C++代码中包含供应商头文件。 与此相关,要使头文件自动适用于C和C++,请执行以下操作:

c_头文件.h
并非所有供应商提供的头文件都包含上述
\uu cplusplus
检测,因此您必须像第一个示例中那样,将它们手动包装在
外部“C”
中。

如果您是针对具有C语言绑定的库进行编译,必须明确地告诉C++库引用的C文件对象不是C++对象,或者C++名称的限制,将阻止正确的链接。通常您可以这样做:

extern "C" {
#include "vendor.h"
}

这将告诉C++编译器,括号之间的符号是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++被忽略的变量ByEvNT。这是真的,因为它应该被C损坏(只是一个前缀)。要解决此问题,请在编译C++时在标题中告诉编译器:

#ifdef __cplusplus
extern "C" BINDING_PROC_BEVNT       b_evnt;
#else
extern BINDING_PROC_BEVNT       b_evnt;
#endif

如果就这些,你就完了。如果你需要更多的符号,你可能会想使用格雷戈的解决方案——但是要注意,这也不是固定的。

< P>你的供应商提供的标题被包含在C++编译单元中,但是它们没有为C++编写。因此,函数的声明是用名字的方式编译的,C++的COMPILR需要支持重载。

头文件需要封装在<代码>外“C”{} /Cuth>块中,以便C++编译器知道这些声明使用C链接。 可能最简单的方法是使用您自己的包装器头,这样做:

#ifndef FOO_WRAPPER_H
#define FOO_WRAPPER_H

#if __cplusplus
extern "C" {
#endif

#include "foo.h"

#if __cplusplus
}
#endif

#endif

并包含YeWrror头,而不是供应商的头——包装器将用于枯萎的C或C++编译。


也可以联系你的图书馆供应商,让他们知道他们应该做这些改变——图书馆的用户不应该做这个工作来使用C++的库。

你不能在C代码中使用C++类,如果你想做的话(不是没有一些解决方案,大部分都是类的)。我试图将C标题集成到C++程序中。可惜有些人不这么做+1.不幸的是,这不起作用,我曾尝试在extern标记中包装.h文件,但是,@dascandy的回答确实解决了问题。。。将C++中的函数指针封装到答复@安特尔斯洛夫提供的,这并没有解决问题,包装函数指针在C++文件中解决了它。谢谢你!供应商文件中的“_cdecl”是否可能告诉编译器将函数视为C风格?我知道这不是它的目的,但可能有副作用?cdecl实际上定义了使用什么调用约定,而不是什么类型的损坏。其他调用约定包括stdcall(Windows函数)、thiscall(隐式的成员函数)和fastcall(优化的stdcall,不经常使用,因为它在大多数情况下都不会更快)。
#ifdef __cplusplus
extern "C" BINDING_PROC_BEVNT       b_evnt;
#else
extern BINDING_PROC_BEVNT       b_evnt;
#endif
#ifndef FOO_WRAPPER_H
#define FOO_WRAPPER_H

#if __cplusplus
extern "C" {
#endif

#include "foo.h"

#if __cplusplus
}
#endif

#endif