2015-06-10 33 views
1

不知道是否extern是处理这种情况的正确方法,但这是我目前尝试的方法。如何在多个文件中定义一个extern函数并指定要使用哪个定义?

我有一个库共享多个项目的通用代码,其中一些库具有不同的引脚配置,必须在库中的_system_pre_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; 
} 

board1.hpp

void Init(void); 

board1.cpp

void Init(void) 
{ 
    // init specific to board 1 
} 

board2.hpp

void Init(void); 

board2.cpp

void Init(void) 
{ 
    // init specific to board 2 
} 

计划是为了实现libary#包括它需要什么板头的项目,而后者将在定义适当的Init()函数。

的main.cpp

#include "board1.hpp" 

int main(int argc, char ** argv) 
{ 
    //... 
} 

但是,它并不像的板头我包括具有超过初始化的()的定义有任何影响。我怎样才能管理这个?或者还有其他一些更适合的范例吗?

+0

它看起来像函数'_system_pre_init(void)'在一个文件中,'main()'在另一个文件中。两个文件是否同时编译允许在编译时指定板类型,或者函数'_system_pre_init(void)'需要在运行时进行初始化决定?什么时候调用'_system_pre_init(void)'而不是'main()'时调用? 'main()'实际上是否需要知道正在使用哪个电路板,或者它可以询问'_system_pre_init(void)'? –

+0

您是否考虑为board1,board2,boardN创建单独的库,并使用唯一适合项目的库? –

+0

主要(或通常是bsp'电路板支持包'的启动代码)必须在硬件上查询某些东西(称之为库存?)以发现代码在哪个板上运行。 OSE和vxWorks都提供了BSP,旨在简化这一过程。你在滚动你自己吗?不管。这是一个典型的鸡与蛋挑战,以获得代码运行在“任一”目标上。大多数设计为在多个配置上运行的代码必须发现该卡的独特之处。通常是一个ROM“库存”,但可能有一张卡有另一个没有的接口。 –

回答

2

提供了板头是试图提供电路板硬件的“编译时间 定义”而不是“运行时发现”。我 希望这是好歹可能

在我的大多数嵌入式系统就业这个想法是在make文件执行。即您要么构建target1,要么构建target2。您正在构建的决定由用户通过选择make文件的正确目标来完成。

在构建整个系统时,您需要指定'all'。

确定目标后,make文件只会生成该目标所需的文件。

未使用条件编译标志。

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

+0

实际上,无论使用'make'还是使用IDE,这都是使用条件编译的好选择。大多数IDE都有某种'make'工具,IDE用它来执行编译命令以最大限度地减少编译的数量。因此,这将是在IDE中设置各种目标的问题,每个配置使用不同版本的board.cpp文件以适应特定的目标板。在Visual Studio中,Configuration Manager通常具有两种配置:调试和发布,但没有什么能够阻止您添加其他配置。 –

+0

我正在使用CMake,所以这个解决方案结束了完美的工作。实施公共库的项目指定了哪个板文件源包含在它的CMakeLists.txt中。允许灵活地保存库中的常用电路板文件,并允许使用库外的特定电路板文件。谢谢 – schumacher574

0

我可以看到两个选项:

  1. 宏 - 在每个标题(board1.hppboard2.hpp)这样定义

#define Init Init_boardN

宏在那里Init_boardN将您的具体功能初始板号N。 这允许您以旧的方式拨打Init作为Init()

  1. Init函数的其他参数(建议枚举)告诉它要初始化哪个板。您可以根据参数调用Init主体中真正的init函数(特定于board)。
+0

不知道我跟着...如果我'#define Init Init_boardN',那么Boot.cpp中的Init()的调用将是不确定的,正确的? – schumacher574

1

看来你想要做的是在编译时决定应用程序将使用哪个板。功能_system_pre_init(void)需要知道哪个板。

我会考虑的方法是将编译器命令行定义为您的构建环境的一部分,它将选择目标板类型。这个编译器命令行定义然后将在文件boot.cpp中使用,以包含board1.cpp或board2.cpp,或者什么。注意我在说板定义C++源文件而不是头文件。

不同版本的电路板将具有相同的功能名称,类别等,但实现方式将与电路板相关。

由于电路板实现文件将被包含在boot.cpp文件中,这意味着包含的任何电路板文件(由编译器命令行选项确定)都可用于功能_system_pre_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; 
} 
+0

好的解决方法,谢谢。结束了make方法,因为它让boot.cpp成为板文件不可知的,但否则这将运行得很好 – schumacher574

相关问题