Borland C ++链接器错误c文件包含

时间:2021-12-17 04:51:19

I'm trying to build a C++ program with borland C++ Builder V5.5. Everything works fine until I tryed to call a function defined in a c file. The compiler works finde but linking is not working. The linker is not able to find the function called from c++ file. The .obj file is gernerated and part of the project xml file. Do anybody now how I can solve this error. To be sure that there are no side effects, I start a new project just calling c function call in constructor. The Project structure looks the following:

我正在尝试使用borland C ++ Builder V5.5构建一个C ++程序。在我尝试调用c文件中定义的函数之前,一切正常。编译器工作finde但链接不起作用。链接器无法找到从c ++文件调用的函数。 .obj文件是gernerated并且是项目xml文件的一部分。现在有人如何解决这个错误。为了确保没有副作用,我启动一个新项目,只是在构造函数中调用c函数调用。 Project结构如下所示:

Form1.h defines Constructor and includes header where the c function is defined

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

Form1.cpp implements Constructor and call the c function

Form1.cpp实现了Constructor并调用了c函数

test.h defines an void function "void abc();"

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

test.c includes test.h and implements an void function "void abc() {}"

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

Unresolved external "abc()" referenced from ...unit1.obj

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

Do anyone have an idea??

有没有人有想法?

Here some code

这里有一些代码

#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;
}

_

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

void abcdefg();

#endif */

_

#include "Multicopter_Model.h"
/* Model initialize function */
void abcdefg()
{

}

3 个解决方案

#1


1  

See C++ FAQ Item [32.4] How can I modify my own C header files so it's easier to #include them in C++ code. (Read the whole of section 32 actually.). Use:

请参阅C ++ FAQ项目[32.4]如何修改自己的C头文件,以便在C ++代码中更容易#include它们。 (实际上阅读第32节的全部内容。)。使用:

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
 extern "C" {
#endif 

void abcdefg();

#ifdef __cplusplus
 }
#endif 
#endif */

#2


3  

I don't know anything about Borland C++ specifically, but if you're declaring something in C++ code that was built as C you typically need to put extern "C" { ... } around the declaration. So, in this case, your Multicopter_Model.h file would want to say something like this:

我对Borland C ++一无所知,但是如果你在C ++代码中声明一些构建为C的东西,你通常需要在声明周围加上extern“C”{...}。因此,在这种情况下,您的Multicopter_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

The reason for this is that in order to support features such as overloading, an object file built from C++ code has something called name mangling applied to it, whereby (e.g.) a function foo that takes an int and returns an int might actually be called something like foo__Rint_Aint to encode that information. (Note 1: Real name mangling conventions are more concise and cryptic. Note 2: In theory the same could be achieved by means other than name mangling, but in practice everyone does name mangling. Note 3: Different compilers do different forms of name mangling.) So when the C++ compiler sees the declaration of abcdefg without the magic annotation to tell it "this is really C, not C++", the name gets mangled and the compiled code actually expects to find a function called (in my made-up name-mangling convention) abcdefg_Rvoid_Anone or something. That function doesn't exist because the C compiler that built Form1.obj doesn't do C++ name-mangling, so the linker can't find what it's looking for.

这样做的原因是,为了支持诸如重载之类的功能,从C ++代码构建的目标文件有一个名为mangling的东西应用于它,其中(例如)一个接受int并返回一个int的函数foo实际上可能被调用类似于foo__Rint_Aint来编码该信息。 (注1:实名修改惯例更简洁,更神秘。注2:理论上可以通过名称修改以外的方式实现同​​样的功能,但实际上每个人都会命名为修改。注3:不同的编译器会执行不同形式的名称修改。)因此,当C ++编译器看到没有魔术注释的abcdefg声明告诉它“这真的是C,而不是C ++”时,名称会被破坏,编译的代码实际上希望找到一个叫做的函数(在我的化妆中)名称修改惯例)abcdefg_Rvoid_Anone等等。该函数不存在,因为构建Form1.obj的C编译器不执行C ++名称修改,因此链接器无法找到它正在查找的内容。

There's a bit of a clue hidden in the linker's error message. You'll notice that it says it couldn't find abcdefg() rather than just abcdefg. That's because the argument list is encoded into the name it's looking for. The linker is kindly reporting a human-readable version of the name rather than whatever mangled monstrosity it was actually looking for.

链接器的错误消息中隐藏着一些线索。你会注意到它说它找不到abcdefg()而不仅仅是abcdefg。那是因为参数列表被编码为它正在寻找的名称。链接器正在报告一个人类可读的名称版本,而不是它实际上正在寻找的任何受损的怪物。

#3


0  

For function overloading and overriding to work in C++, all C++ compilers adds information to the function name (see http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B). C doesn't, so when you have a prototype in C++ the generated symbol name will not be the same as the one generated by a C compiler.

对于函数重载和覆盖在C ++中工作,所有C ++编译器都会向函数名称添加信息(请参阅http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B)。 C没有,因此当您在C ++中使用原型时,生成的符号名称将与C编译器生成的符号名称不同。

See the other answers on how to fix this.

请参阅有关如何解决此问题的其他答案。

#1


1  

See C++ FAQ Item [32.4] How can I modify my own C header files so it's easier to #include them in C++ code. (Read the whole of section 32 actually.). Use:

请参阅C ++ FAQ项目[32.4]如何修改自己的C头文件,以便在C ++代码中更容易#include它们。 (实际上阅读第32节的全部内容。)。使用:

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
 extern "C" {
#endif 

void abcdefg();

#ifdef __cplusplus
 }
#endif 
#endif */

#2


3  

I don't know anything about Borland C++ specifically, but if you're declaring something in C++ code that was built as C you typically need to put extern "C" { ... } around the declaration. So, in this case, your Multicopter_Model.h file would want to say something like this:

我对Borland C ++一无所知,但是如果你在C ++代码中声明一些构建为C的东西,你通常需要在声明周围加上extern“C”{...}。因此,在这种情况下,您的Multicopter_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

The reason for this is that in order to support features such as overloading, an object file built from C++ code has something called name mangling applied to it, whereby (e.g.) a function foo that takes an int and returns an int might actually be called something like foo__Rint_Aint to encode that information. (Note 1: Real name mangling conventions are more concise and cryptic. Note 2: In theory the same could be achieved by means other than name mangling, but in practice everyone does name mangling. Note 3: Different compilers do different forms of name mangling.) So when the C++ compiler sees the declaration of abcdefg without the magic annotation to tell it "this is really C, not C++", the name gets mangled and the compiled code actually expects to find a function called (in my made-up name-mangling convention) abcdefg_Rvoid_Anone or something. That function doesn't exist because the C compiler that built Form1.obj doesn't do C++ name-mangling, so the linker can't find what it's looking for.

这样做的原因是,为了支持诸如重载之类的功能,从C ++代码构建的目标文件有一个名为mangling的东西应用于它,其中(例如)一个接受int并返回一个int的函数foo实际上可能被调用类似于foo__Rint_Aint来编码该信息。 (注1:实名修改惯例更简洁,更神秘。注2:理论上可以通过名称修改以外的方式实现同​​样的功能,但实际上每个人都会命名为修改。注3:不同的编译器会执行不同形式的名称修改。)因此,当C ++编译器看到没有魔术注释的abcdefg声明告诉它“这真的是C,而不是C ++”时,名称会被破坏,编译的代码实际上希望找到一个叫做的函数(在我的化妆中)名称修改惯例)abcdefg_Rvoid_Anone等等。该函数不存在,因为构建Form1.obj的C编译器不执行C ++名称修改,因此链接器无法找到它正在查找的内容。

There's a bit of a clue hidden in the linker's error message. You'll notice that it says it couldn't find abcdefg() rather than just abcdefg. That's because the argument list is encoded into the name it's looking for. The linker is kindly reporting a human-readable version of the name rather than whatever mangled monstrosity it was actually looking for.

链接器的错误消息中隐藏着一些线索。你会注意到它说它找不到abcdefg()而不仅仅是abcdefg。那是因为参数列表被编码为它正在寻找的名称。链接器正在报告一个人类可读的名称版本,而不是它实际上正在寻找的任何受损的怪物。

#3


0  

For function overloading and overriding to work in C++, all C++ compilers adds information to the function name (see http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B). C doesn't, so when you have a prototype in C++ the generated symbol name will not be the same as the one generated by a C compiler.

对于函数重载和覆盖在C ++中工作,所有C ++编译器都会向函数名称添加信息(请参阅http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B)。 C没有,因此当您在C ++中使用原型时,生成的符号名称将与C编译器生成的符号名称不同。

See the other answers on how to fix this.

请参阅有关如何解决此问题的其他答案。