C代码编译为C ++,但不是C编译

时间:2010-06-29 17:11:17

标签: c++ c visual-studio

  

可能重复:
  Convert some code from C++ to 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

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:5)

听起来Inp32Out32是在C ++文件/库中外部定义的,因此您需要将它们标记为这样,以便编译器知道它们的名称将被破坏:

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

答案 2 :(得分: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"并调用包装器函数,这些函数只调用现有的C ++函数来完成工作。

答案 3 :(得分:2)

它似乎不是编译器错误,而是链接器错误。链接器无法找到Inp32Out32的定义。您是否链接到包含定义的库?你拼错了吗?