Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在多个文件中定义extern函数并指定要使用的定义?_C++_C Preprocessor - Fatal编程技术网

C++ 如何在多个文件中定义extern函数并指定要使用的定义?

C++ 如何在多个文件中定义extern函数并指定要使用的定义?,c++,c-preprocessor,C++,C Preprocessor,不确定extern是否是处理这种情况的正确方法,但这正是我目前尝试的方法 我有一个跨多个项目共享公共代码的库,其中一些项目具有不同的引脚配置,必须在库中的\u system\u pre\u init()函数期间执行这些配置(由于微处理器行为,在main()之前调用) 例: boot.cpp extern void Init(void); // called prior to main() due to microprocessor behavior extern "C" int _system

不确定
extern
是否是处理这种情况的正确方法,但这正是我目前尝试的方法

我有一个跨多个项目共享公共代码的库,其中一些项目具有不同的引脚配置,必须在库中的
\u system\u pre\u init()
函数期间执行这些配置(由于微处理器行为,在
main()
之前调用)

例:

boot.cpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
董事会1.hpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
董事会1.cpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
董事会2.hpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
董事会2.cpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
该计划是为了实现库的项目#包括它需要的任何板头,这将反过来定义适当的Init()函数

main.cpp

extern void Init(void);

// called prior to main() due to microprocessor behavior
extern "C" int _system_pre_init(void)
{
    Init();

    return 1;
}
void Init(void);
void Init(void)
{
    // init specific to board 1
}
void Init(void);
void Init(void)
{
    // init specific to board 2
}
#include "board1.hpp"

int main(int argc, char ** argv)
{
    //...
}
但是,我所包含的board标头似乎对Init()的定义没有任何影响。我该怎么办?或者还有其他更适合这里的范例吗?

我可以看到两种选择:

  • 宏-在每个标题(
    board1.hpp
    board2.hpp
    )中定义如下宏
  • #定义初始初始板n

    其中,
    Init_boardN
    是您初始化board number
    N
    的特定功能。 这允许您以旧的方式调用
    Init()

  • Init
    函数(建议的枚举)的附加参数,告诉它初始化哪个板。您可以根据参数从
    init
    的主体调用real init函数(特定于线路板)

  • 似乎您想要做的是在编译时决定应用程序将使用什么板。函数
    \u system\u pre\u init(void)
    需要知道哪个板

    我将考虑将编译器命令行定义为构建环境的一部分,它将选择目标板类型。然后,此编译器命令行定义将在boot.cpp文件中使用,以包括board1.cpp或board2.cpp,或任何内容。注意,我是在说板定义C++源文件,而不是头文件。

    不同版本的电路板都具有相同的函数名、类等,尽管实现是特定于电路板的

    由于board实现文件将包含在boot.cpp文件中,这意味着包含的任何board文件(由编译器命令行选项确定)都将可用于函数
    \u system\u pre\u init(void)
    以及其他代码

    因此,例如,您可能有一个编译器命令行选项
    -DBOARDTYPE=1
    -DBOARDTYPE=2
    ,然后在boot.cpp文件中有预处理器宏,例如:

    #if BOARDTYPE == 1
    #include "board1.cpp"
    #elif BOARDTYPE == 2
    #include "board2.cpp"
    #endif
    
    // called prior to main() due to microprocessor behavior
    extern "C" int _system_pre_init(void)
    {
        Init();
    
        return 1;
    }
    
    提供board头是为了提供“编译时” 板硬件的“定义”,而不是“运行时发现”。我是 希望这在某种程度上是可能的

    在大多数嵌入式系统中,这个想法都是在make文件中实现的。i、 e.您要么构建target1,要么构建target2。用户通过选择make文件的正确目标来决定要构建哪个文件

    在构建整个系统时,您可以指定“all”

    识别目标后,make文件仅构建该目标所需的文件

    未使用条件编译标志


    但是,也许这是没有用的。。。如果不使用make.

    函数
    \u system\u pre\u init(void)
    在一个文件中,而
    main()
    在另一个文件中。这两个文件是同时编译的,允许在编译时指定电路板类型,还是函数
    \u system\u pre\u init(void)
    需要在运行时做出初始化决定?实际何时调用
    \u system\u pre\u init(void)
    与何时调用
    main()
    相比?
    main()
    是否真的需要知道正在使用什么板,或者它是否可以询问
    \u system\u pre\u init(void)
    ?您是否考虑过为board1、board2、boardN创建单独的库,并使用唯一适合项目的库?main(或者通常是bsp“board support package”的启动代码)必须查询硬件上的某些内容(称之为inventory?)才能发现代码在哪个板上运行。OSE和vxWorks都提供了BSP,旨在简化此操作。你要自己滚吗?不管怎样这是一个典型的鸡和蛋的挑战,让代码运行在“任意”目标上。大多数设计用于在多个配置上运行的代码必须发现该卡的独特之处。通常是一个rom“目录”,但可能有一个卡有一个接口,而另一个没有。@RichardChambers更正,不同的文件。它们是同时编译的<代码>\u system\u pre\u init在
    main
    之前调用
    \u system\u pre\u init
    不知道使用的是什么板,这才是问题的根源。@RSahu不幸的是,每个板的单独库对我的情况不是一个理想的解决方案。我不确定是否遵循……如果我
    \define init init\u boardN
    ,那么boot.cpp中对init()的调用将是未定义的,正确吗?实际上,无论是使用
    make
    还是使用IDE,这都是使用条件编译的一个很好的替代方法。大多数IDE都有一种
    make
    功能,IDE使用该功能来执行build命令,以最大限度地减少编译量,因此只需在IDE中设置不同的目标,每个配置使用不同版本的board.cpp文件,以适合特定的目标板。例如,在VisualStudio中有一个配置管理器,它通常有两个配置,调试和发布,但是没有什么可以阻止您添加其他配置