【问题标题】:Borland C++ linker error c file includeBorland C++ 链接器错误 c 文件包括
【发布时间】:2025-12-17 17:20:12
【问题描述】:

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

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

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

test.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;
}

_

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

void abcdefg();

#endif */

_

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

}

【问题讨论】:

    标签: c++ linker include borland-c++


    【解决方案1】:

    我对 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
    

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

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

    【讨论】:

      【解决方案2】:

      请参阅 C++ 常见问题解答项目 [32.4] How can I modify my own C header files so it's easier to #include them in C++ code。 (实际上阅读整个section 32。)。使用:

      #ifndef RTW_HEADER_Multicopter_Model_h_
      #define RTW_HEADER_Multicopter_Model_h_
      
      #ifdef __cplusplus
       extern "C" {
      #endif 
      
      void abcdefg();
      
      #ifdef __cplusplus
       }
      #endif 
      #endif */
      

      【讨论】:

        【解决方案3】:

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

        请参阅其他答案以了解如何解决此问题。

        【讨论】: