博尔兰C++;链接器错误c文件包括 我试图用Borland C++ +Builder V5.5构建一个C++程序。一切正常,直到 我试图调用c文件中定义的函数。编译器在finde中工作,但链接不工作。链接器无法找到从C++文件调用的函数。.obj文件是生成的,是项目xml文件的一部分。现在有人知道我如何解决这个错误了吗。 为了确保没有副作用,我启动了一个新项目,只需在构造函数中调用c函数。项目结构如下所示:

博尔兰C++;链接器错误c文件包括 我试图用Borland C++ +Builder V5.5构建一个C++程序。一切正常,直到 我试图调用c文件中定义的函数。编译器在finde中工作,但链接不工作。链接器无法找到从C++文件调用的函数。.obj文件是生成的,是项目xml文件的一部分。现在有人知道我如何解决这个错误了吗。 为了确保没有副作用,我启动了一个新项目,只需在构造函数中调用c函数。项目结构如下所示:,c++,linker,include,borland-c++,C++,Linker,Include,Borland C++,Form1.h定义构造函数,包括定义c函数的头文件 Form1.cpp实现构造函数并调用c函数 h定义了一个void函数“void abc();” test.c包括test.h并实现一个void函数“void abc(){}” 从…unit1.obj引用的未解析外部“abc()” 有人有主意吗 这里有一些代码 #include <vcl.h> #pragma hdrstop #include "Multicopter_Model.h" #include "Unit1.h" #pra

Form1.h定义构造函数,包括定义c函数的头文件

Form1.cpp实现构造函数并调用c函数

h定义了一个void函数“void abc();”

test.c包括test.h并实现一个void函数“void abc(){}”

从…unit1.obj引用的未解析外部“abc()”

有人有主意吗

这里有一些代码

#include <vcl.h>
#pragma hdrstop
#include "Multicopter_Model.h"
#include "Unit1.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
abcdefg();
return;
}
_

见C++常见问题解答。(实际阅读全文。)。使用:

见C++常见问题解答。(实际阅读全文。)。使用:


<>我对Borland C++一无所知,但是如果你在C++代码中声明了一些东西,它们是作为C来构建的,那么你通常需要在声明中放置<代码>外“C”{} }。因此,在本例中,您的
multipter_Model.h
文件会这样说:

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
extern "C" {
#endif

void abcdefg();

#ifdef __cplusplus
}
#endif

#endif

之所以这样,是为了支持诸如重载之类的特性,由C++代码构建的对象文件有一个名为“名称”的应用程序,由此(例如)一个函数

foo
接受一个
int
并返回一个
int
实际上可能被称为
foo\uuuu Rint\uu Aint
来编码该信息。(注1:实名篡改约定更简洁、更隐晦。注2:理论上,除了名称篡改以外,其他方法也可以实现相同的约定,但实际上每个人都会进行名称篡改。注3:不同的编译器会进行不同形式的名称篡改。)因此,当C++编译器看到了<代码> ABCDEGG < />的声明时,没有魔术注释来告诉它“这是真的C,不是C++”,这个名字被篡改了,编译代码实际上希望找到一个函数(名为“我的名字命名规则”):代码> ABCFDGGRVIDIDAANON/CODER >或其他什么。这个函数不存在,因为编译了<代码> Fr.1.Obj/Obj>的C编译器不做C++名字的修改,所以链接器找不到它想要的东西。
链接器的错误消息中隐藏了一些线索。您会注意到,它说它找不到
abcdefg()
,而只是
abcdefg
。这是因为参数列表被编码到它要查找的名称中。链接器正在亲切地报告一个人类可读版本的名称,而不是它实际上寻找的任何被篡改的怪物。

< P>我对Borland C++一无所知,但是如果你在C++代码中声明了一些被构建为C的东西,那么你通常需要在声明中放置“代码-ExtEnter”C“{…} //Cube”。因此,在本例中,您的
multipter_Model.h
文件会这样说:

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
extern "C" {
#endif

void abcdefg();

#ifdef __cplusplus
}
#endif

#endif

之所以这样,是为了支持诸如重载之类的特性,由C++代码构建的对象文件有一个名为“名称”的应用程序,由此(例如)一个函数

foo
接受一个
int
并返回一个
int
实际上可能被称为
foo\uuuu Rint\uu Aint
来编码该信息。(注1:实名篡改约定更简洁、更隐晦。注2:理论上,除了名称篡改以外,其他方法也可以实现相同的约定,但实际上每个人都会进行名称篡改。注3:不同的编译器会进行不同形式的名称篡改。)因此,当C++编译器看到了<代码> ABCDEGG < />的声明时,没有魔术注释来告诉它“这是真的C,不是C++”,这个名字被篡改了,编译代码实际上希望找到一个函数(名为“我的名字命名规则”):代码> ABCFDGGRVIDIDAANON/CODER >或其他什么。这个函数不存在,因为编译了<代码> Fr.1.Obj/Obj>的C编译器不做C++名字的修改,所以链接器找不到它想要的东西。
链接器的错误消息中隐藏了一些线索。您会注意到,它说它找不到
abcdefg()
,而只是
abcdefg
。这是因为参数列表被编码到它要查找的名称中。链接器正在亲切地报告一个人类可读版本的名称,而不是它实际寻找的任何被篡改的怪物。

< P>函数重载和重写C++中的所有工作,所有C++编译器都会向函数名添加信息(参见)。C没有,所以当C++中有一个原型时,生成的符号名称将与C编译器生成的符号名不一样。
<> P> >关于如何修复这个问题,

< P>函数重载和C++重写,所有C++编译器将函数添加到函数名(参见)。C没有,所以当C++中有一个原型时,生成的符号名称将与C编译器生成的符号名不一样。 请参阅有关如何解决此问题的其他答案

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
 extern "C" {
#endif 

void abcdefg();

#ifdef __cplusplus
 }
#endif 
#endif */
#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
extern "C" {
#endif

void abcdefg();

#ifdef __cplusplus
}
#endif

#endif