2010-06-29 56 views
4

Possible Duplicate:
Convert some code from C++ to CC代码编译为C++,但不是为C

我有一个看起来是直的。当我告诉编译器一些代码(我使用Visual Studio 2008 Express的)编译它作为C++,它编译和链接罚款。当我尝试编译为C,虽然,它抛出这个错误:

1>InpoutTest.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>InpoutTest.obj : error LNK2019: unresolved external symbol [email protected] 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

任何帮助,将不胜感激。

+0

这些天C是否会使用错位的名字?我正在查看链接器错误中的“@ 4”和“@ 8”。看起来不像C++的名称,除非我很困惑,但那些肯定不是未修饰的函数名称。 – Steve314 2010-06-29 17:19:22

+2

这只是你以前的问题的一个小改写:http://stackoverflow.com/questions/3142420/convert-some-code-from-c-to-c。尽量不要加倍张贴。 – 2010-06-29 17:21:01

+0

@Evan:我再次问,因为我没有得到新的问题。抱歉。 – 2010-06-29 17:23:51

回答

6

您正在尝试链接到C++函数,这是因为名称修改 - 链接器不知道在哪里查找函数。如果您想从C++调用C函数,则必须将其标记为extern“C”。 C不支持extern“C++” - 据我所知。其他答案之一说有。或者,将它的源代码重新编译为C.

编辑:如果可以编译为C++,为什么要编译为C?

+0

我需要从C项目调用Out32,如果我尝试编译为C++,会抛出一堆错误。 – 2010-06-29 17:43:03

+0

我将lib的源代码重新编译为C,并且工作正常。 (在我将afxres.h的引用更改为winres.h后) – 2010-06-29 17:48:07

5

这听起来像Inp32Out32在一个C++文件/库外部定义的,所以你需要将它们标记为这样所以编译器知道他们的名字如何,将被截断:

extern "C++" { 
    short _stdcall Inp32(short PortAddress); 
    void _stdcall Out32(short PortAddress, short data); 
} 
+0

这给了错误C2059:语法错误:'字符串' – 2010-06-29 17:19:41

+0

是否有'extern“C++”'?它可能是不可移植的?我会在头文件中使用'extern“C'',在那些函数被压缩的头文件中,使用'#ifdef'来保护,这样只有C++编译器才能看到它。 C编译器已经使用C调用约定。 – Steve314 2010-06-29 17:25:25

+0

@Steve虽然以另一种方式做这件事更为常见,我不确定可移植性,因为我从来没有真正需要使用它。如果它是一个库,他不控制/有源码,但他没有多少选择,尽管 – 2010-06-29 17:30:18

2

它不似乎是一个编译器错误,而是一个链接器错误。链接器找不到Inp32Out32的定义。你链接到包含定义的库吗?你拼写正确吗?

+0

我所做的唯一的事情是将文件的设置更改为C而不是C++进行编译。我没有改变任何链接或任何东西。有什么我需要改变链接器设置? – 2010-06-29 17:21:35

5

如果您需要从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"并调用封装功能,这只是调用EXI蜇C++函数来完成这项工作。