简体   繁体   English

理想的跨平台库

[英]Ideal cross-platform library

One has to create a new software library. 必须创建一个新的软件库。 This library has no system I/O routines and contains only Init(config), Run(some_data_inputs), and DeInit(config) functions and a few typedefs and defines. 该库没有系统I / O例程,仅包含Init(config),Run(some_data_inputs)和DeInit(config)函数以及一些typedef和定义。 Run() function just processes given input data and generates output data, no interrupts, threads, locks, etc. However, it requires some RAM for its internal needs. Run()函数仅处理给定的输入数据并生成输出数据,没有中断,线程,锁等。但是,它需要一些RAM才能满足其内部需求。 The interface is described in a header file and a static library contains the implementation. 该接口在头文件中描述,并且静态库包含实现。

This library must be as much multi-plarform as possible. 该库必须具有尽可能多的平台。 It must be matter of minutes to port this library to any new platform onto any new OS+CPU. 将这个库移植到任何新平台到任何新的OS + CPU都必须花费几分钟。 Sometimes this lib can be used even on the platforms without operating systems. 有时甚至在没有操作系统的平台上也可以使用此库。

So, before starting development, one has to decide: 因此,在开始开发之前,必须决定:

  1. Must this lib be written in ANSI-C or even in a sub-set of ANSI-C because some platforms may not support ANSI-C completely? 因为某些平台可能不完全支持ANSI-C,所以该库必须用ANSI-C或什至是ANSI-C的子集编写吗?
  2. Whether to write an abstraction layer, which encapsulates an underlying OS+CPU? 是否编写一个封装底层OS + CPU的抽象层?
  3. Should this abstraction layer include its own memory manager (malloc/free routines) or all platforms today provide it already? 这个抽象层应该包括它自己的内存管理器(malloc / free例程)还是当今所有平台都已经提供了它?
  1. Must this lib be written in ANSI-C or even in a sub-set of ANSI-C because some platforms may not support ANSI-C completely? 因为某些平台可能不完全支持ANSI-C,所以该库必须用ANSI-C或什至是ANSI-C的子集编写吗?

Neither, I suggest ISO C. ANSI has not been the standards body for C since 1990. ISO C90 should be ubiquitous. 我也不建议使用ISOC。自1990年以来,ANSI一直不是C的标准机构。ISOC90应该无处不在。 Depending on the target platform capabilities, the accompanying Standard Library may be a subset, or may require implementation of stubs to port it to a particular target. 根据目标平台的功能,随附的标准库可能是子集,或者可能需要存根实现才能将其移植到特定目标。 The Newlib C library, often used in embedded systems using GCC for example, requires basic I/O stubs (not required in this case since you have specified that no I/O operations take place) and the sbrk() function to be implemented. 例如,Newlib C库通常在使用GCC的嵌入式系统中使用,它需要基本的I / O存根(在这种情况下不需要,因为您指定了不进行I / O操作),并且需要实现sbrk()函数。 sbrk() provides memory to the heap allocator; sbrk()为堆分配器提供内存; it requires no OS, or it could request memory from an OS. 它不需要操作系统,也可以从操作系统请求内存。

  1. Whether to write an abstraction layer, which encapsulates an underlying OS+CPU? 是否编写一个封装底层OS + CPU的抽象层?

Give the restrictions you have imposed on this library design, it seems that the are no OS issues. 给出您对此库设计施加的限制,看来这不是操作系统问题。 The standard library provides the requirements for memory allocation. 标准库提供了内存分配的要求。

  1. Should this abstraction layer include its own memory manager (malloc/free routines) or all platforms today provide it already? 这个抽象层应该包括它自己的内存管理器(malloc / free例程)还是当今所有平台都已经提供了它?

Answered in (1); 在(1)中回答; provide them as part of the standard library or use the existing implementation for the platform. 提供它们作为标准库的一部分,或使用平台的现有实现。

In the end what you need is to write your library to use C90 and the standard library, then it is simply a matter of porting the standard library to the target if it is not already done. 最后,您需要编写您的库以使用C90和标准库,然后只需将标准库移植到目标即可(如果尚未完成)。

In reverse order: 以相反的顺序:

(3). (3)。 You need your own memory management routines, if not for any other reason, then simply because you expect that it may be ported to a bare platform without an underlying OS. 您需要自己的内存管理例程,如果不是出于任何其他原因,那么仅仅是因为您希望将其移植到没有底层操作系统的裸机上即可。 Then you also need an implementation for pretty much everything else: string libraries, math libraries etc. You have to either code them yourself, or try to find ready-made code libraries that provide them for each platform. 然后,您还需要实现几乎所有其他功能的实现:字符串库,数学库等。您必须自己编写代码,或者尝试查找为每个平台提供它们的现成代码库。

(2). (2)。 The OS and CPU are somewhat orthogonal variables. OS和CPU在某种程度上是正交变量。 You would probably have a better time creating two abstraction layers (one for different operating systems, one for different hardware platforms) and then include/override definitions as necessary for each new platform. 您可能会有更好的时间来创建两个抽象层(一个用于不同的操作系统,一个用于不同的硬件平台),然后根据需要为每个新平台包括/覆盖定义。 But yes, an abstraction layer is a more manageable solution than riddling your code with whole hordes of #ifdefs. 但是,是的,比起用大量#ifdefs来代替代码,抽象层是一种更易于管理的解决方案。

(1). (1)。 This is not an easy question to answer. 这不是一个容易回答的问题。 For example if you expect your library to run on an embedded system or even a microcontroller then it's quite probable that not all of ANSI C features are available, depending on the maturity of the development tools. 例如,如果您希望库在嵌入式系统甚至微控制器上运行,则很有可能并非所有ANSI C功能都可用,这取决于开发工具的成熟度。 There could also be restrictions not necessarily related to the language itself. 也可能存在不一定与语言本身相关的限制。 Hardware floating point units are relatively rare in embedded systems. 硬件浮点单元在嵌入式系统中相对较少。 Stack sizes could be limited etc. I suggest that you make a survey of the platforms that you are interested in and try to select a common subset. 堆栈大小可能会受到限制等。我建议您对自己感兴趣的平台进行调查,并尝试选择一个通用子集。

(0). (0)。 You could very well find from an economic (or even a feasibility) point of view that it is preferrable to develop for a rather rich subset that is supported in your most common target platforms and refactor your code if you encounter a new platform. 从经济(甚至可行性)的角度来看,您可能会发现最好开发一个最常见的目标平台支持的相当丰富的子集,并在遇到新平台时重构代码。 Trying to restrict youserlf to the most common subset could essentially cripple both your development effort and the effectiveness of your library in slightly more capable systems. 试图将自己限制在常见的子集上,实际上可能会削弱您的开发工作以及在功能稍强的系统中库的有效性。

(-1). (-1)。 You should realise from the scarsity (or even complete lack) of libraries with your required level of portability that what you want to achieve is not going to be easy. 您应该从缺乏(甚至完全缺少)具有所需可移植性级别的库中意识到,要实现的目标并不容易。 Be prepared! 做好准备!

There are lots of different styles of system architecture, and writing something non-trivial that is easily portable to all of them is probably not possible. 有许多不同样式的系统架构,并且不可能编写容易移植到所有这些工具的非平凡的东西。

I suggest, though, that you write your interfaces so that they take in a pointer to a structure that contains all of the system functions that are needed. 但是,我建议您编写接口,以便它们采用指向包含所有所需系统功能的结构的指针。 You could do this either in every call or just once in the init routine. 您可以在每个调用中执行此操作,也可以在init例程中执行一次。

This way you will have limited the places where differences in the code for different architectures to code which generates the structure of function pointers. 这样,您将把针对不同体系结构的代码中的差异限制在生成函数指针结构的代码中。

This also makes it so that you can easily test the library for handling failure of one or more of these routines by altering just this structure, so that if you wanted to test for proper handling of malloc failure then you just replace the malloc pointer in the struct with one that fails. 这也使得您只需更改此结构即可轻松测试该库是否处理了一个或多个例程的失败,因此,如果您想测试对malloc失败的正确处理,则只需替换malloc指针即可。与失败的结构。

You might also wrap the system functions on a particular system with functions that give you the interface your library expects as well as at least partially handling errors (like translating to/from errno ). 您还可以将系统函数包装在特定系统上,这些函数可以为您的库提供期望的接口,并且至少可以部分地处理错误(例如,与errno )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM