C代码编译为C++,但不是C [重复]
Posted
技术标签:
【中文标题】C代码编译为C++,但不是C [重复]【英文标题】:C code compiles as C++, but not as C [duplicate] 【发布时间】:2010-06-29 17:11:17 【问题描述】:可能重复:Convert some code from C++ to C
我有一些看起来是纯 C 的代码。当我告诉编译器(我使用 Visual Studio 2008 Express)将其编译为 c++ 时,它可以正常编译和链接。但是,当我尝试将其编译为 C 时,它会引发此错误:
1>InpoutTest.obj : error LNK2019: unresolved external symbol _Out32@8 referenced in function _main
1>InpoutTest.obj : error LNK2019: unresolved external symbol _Inp32@4 referenced in function _main
代码使用 Inpout.dll 读取和写入并行端口。我有 Inpout.lib 和 Inpout.dll。代码如下:
// InpoutTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
/* ----Prototypes of Inp and Outp--- */
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
/*--------------------------------*/
int main(int argc, char* argv[])
int data;
if(argc<3)
//too few command line arguments, show usage
printf("Error : too few arguments\n\n***** Usage *****\n\nInpoutTest read <ADDRESS> \nor \nInpoutTest write <ADDRESS> <DATA>\n\n\n\n\n");
else if(!strcmp(argv[1],"read"))
data = Inp32(atoi(argv[2]));
printf("Data read from address %s is %d \n\n\n\n",argv[2],data);
else if(!strcmp(argv[1],"write"))
if(argc<4)
printf("Error in arguments supplied");
printf("\n***** Usage *****\n\nInpoutTest read <ADDRESS> \nor \nInpoutTest write <ADDRESS> <DATA>\n\n\n\n\n");
else
Out32(atoi(argv[2]),atoi(argv[3]));
printf("data written to %s\n\n\n",argv[2]);
return 0;
我之前问错了这个问题,here。
任何帮助将不胜感激。
【问题讨论】:
这些天 C 是否使用重命名?我正在查看链接器错误中的@4
和@8
。看起来不像 C++ 名称修饰,除非我很困惑,但这些肯定不是未修饰的函数名称。
这只是对您上一个问题的小改写:***.com/questions/3142420/…。尽量不要重复发帖。
@Evan:我重新提问是因为我没有对另一个问题提出新的意见。对不起。
@Steve Visual Studio 将 _stdcall C 函数转换为 _name@number-of-bytes-passed-as-arguments; Inp32
有 4 个字节的参数,而 Out32
有 8 个。(reference)
@Michael - 有道理,谢谢
【参考方案1】:
您正在尝试从 C 链接到 C++ 函数。由于名称修改,这不起作用 - 链接器不知道在哪里查找您的函数。如果要从 C++ 调用 C 函数,则必须将其标记为 extern "C"。据我所知,C 不支持外部“C++”。其他答案之一说有。或者,将其源代码重新编译为 C。
编辑:如果可以编译为 C++,为什么还要编译为 C?
【讨论】:
我需要从 C 项目中调用 Out32,如果我尝试编译为 C++,则会引发一堆错误。 我将 lib 的源代码重新编译为 C,它可以工作。 (在我将引用从 afxres.h 更改为 winres.h 之后)【参考方案2】:听起来 Inp32
和 Out32
是在 C++ 文件/库中外部定义的,因此您需要将它们标记为这样,以便编译器知道它们的名称将如何被破坏:
extern "C++"
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
【讨论】:
这给出了错误 C2059: syntax error : 'string' 有extern "C++"
吗?会不会是非便携的?我会在标明这些函数的头文件中使用extern "C"
,并使用#ifdef
保护,这样只有C++ 编译器才能看到它。 C 编译器已经使用 C 调用约定。
@Steve 有,尽管以另一种方式做更常见;我不确定可移植性,因为我实际上从未需要使用它。如果它是一个图书馆,他无法控制/拥有资源,因为他没有太多选择
extern C++
是可移植的 C++,但在编译 C 翻译单元时不能使用(因为它不是 C),因此在这种特殊情况下不合适。 extern "C++"
很少有用 - 有一些 C++ 结构不能在 extern "C"
块内,但您通常不需要将它们放在那里。有关 extern "C++"
的使用示例,请参见 Microsoft 的 winnt.h。
@Michael - 如果他没有源代码,那么肯定要做的是编写一个小型适配器库吗?使用 C++ 编译的 C 链接函数调用提供的 C++ 函数。【参考方案3】:
如果您需要从 C 代码调用 C++ 例程,则 C++ 例程需要具有“C”链接,这是通过将函数标记为 extern "C"
来完成的。这需要在 C++ 端完成。
如果您能够更改现有的 C++ 代码,请将以下内容作为 Inp32()
和 Outp32()
的原型。这应该在任何调用或定义 Inp32()
或 Outp32()
函数的标头中 - 无论是 C 还是 C++ 代码:
#ifdef __cplusplus
extern "C"
#endif
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
#ifdef __cplusplus
#endif
这会将这些函数标记为具有 C 调用约定,并且这些函数可由 C 或 C++ 代码调用。
如果您无法更改 C++ 代码,您可以在自己的 C++ 模块中为 C++ 函数创建自己的 C 兼容包装器:
wrappers.h 头文件:
// in wrappers.h
// C-callable wrappers
#ifndef WRAPPERS_H
#define WRAPPERS_H
#ifdef __cplusplus
extern "C"
#endif
short Inp32_wrapper( short PortAddress);
void Out32_wrapper( short PortAddress, short data);
#ifdef __cplusplus
#endif
#endif /* WRAPPERS_H */
还有,wrappers.cpp 实现:
// in wrappers.cpp file:
#include "wrappers.h"
// prototypes for the C++ functions - these really should be in a
// header file...
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
// implementation of the wrappers
short Inp32_wrapper( short PortAddress)
return Inp32( PortAddress);
void Out32_wrapper( short PortAddress, short data)
Out32( PortAddress, data);
现在您的 C 代码可以#include "wrappers.h"
并调用包装函数,这些函数将简单地调用现有的 C++ 函数来完成工作。
【讨论】:
【参考方案4】:这似乎不是编译器错误,而是链接器错误。链接器找不到Inp32
和Out32
的定义。您是否链接到包含定义的库?你拼写正确吗?
【讨论】:
我唯一做的就是更改文件的设置以编译为 C 而不是 C++。我没有改变任何链接或任何东西。我需要更改链接器设置吗?以上是关于C代码编译为C++,但不是C [重复]的主要内容,如果未能解决你的问题,请参考以下文章