我有一些看起来很直接的代码。当我告诉编译器(我使用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。
任何帮助都将不胜感激。
答案 0 :(得分:6)
您正在尝试从C链接到C ++函数。由于名称修改而无效 - 链接器不知道在哪里查找您的函数。如果要从C ++调用C函数,则必须将其标记为extern“C”。 C不支持extern“C ++” - 据我所知。其中一个答案说有。或者,将其源代码重新编译为C.
编辑:如果可以编译为C ++,为什么还要编译为C?
答案 1 :(得分:5)
听起来Inp32
和Out32
是在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)
它似乎不是编译器错误,而是链接器错误。链接器无法找到Inp32
和Out32
的定义。您是否链接到包含定义的库?你拼错了吗?