第一节 APR代码风格(libapr skeleton code)

第一节 APR代码风格(libapr skeleton code)

I believe it is a good idea to write 'skeleton code' at first, when you
start to learn a new library or a new framework programming. 'skeleton code' is
the smallest source code, but you can compile and execute it (although it
usually do nothing useful).

我相信当你开始学习一个新的框架或是新的程序库时,首先了解他的基础代码一个好主意。基础代码是一段简单的代码,但是你可以编译和运行它。(尽管这些代码可能没什么用处)

Fortunately, libapr's skeleton code is much simpler than other modern
frameworks. Let's take a look at apr-skeleton.c. We call apr_initialize() at
the initialization, and call apr_terminate() at the finalization. That's all.
As you can imagine, the code does nothing.

幸运的是APR的基础代码较现在流行的一些框架的基础代码要小很多。我们看一下apr-skeleton.c这个文件,在程序初始化的时候我们需要调用apr_initialize()函数对整个程序进行初始化,在程序结束的时候调用apr_terminate(),APR的基础代码仅此而已。

libapr is not a framework library. Accordingly, libapr doesn't help you
to design the whole structure of the source code. There are pros and cons. Pros
is that it is easy to use libapr with the other existing code. Cons is that you
need to design the whole structure of the code by yourself when you use libapr.

APR不是一个框架程序,因此APR不能帮你设计整个代码的结构,对于你来讲APR这样的设计有好有坏,好的是APR可以非常容易和你现有的代码结合,不好的方面是你需要设计整个代码的结构当你使用APR的时候。

Here, we have some libapr programming styles and rules:

  • naming rule is very simple and clear.
  • opaque data types are commonly used (a.k.a. incomplete types)
  • most of return types are apr_status_t. As a result, result-arguments are commonly used.
  • memory pool rules

这里有一些APR的代码风格

  • 命名规则是非常间接
  • 经常使用不透明的数据类型
  • 大多数返回类型是apr_status_t.
  • 内存池规则

We are able to see these styles in the following code.

下面的代码反映了这些代码风格

/* excerpted from mp-sample.c */
apr_status_t rv;
apr_pool_t *mp;
rv = apr_pool_create(&mp, NULL);

I will describe the meaning of the code. Here, please take a look at only style. You can see apr_ prefix. The apr_ prefix indicates that the symbol is in libapr naming scope. You can see _t suffix. It indicates that the symbol is a type name.

我们以后讨论这些代码的含义,这里我只关注一下APR的代码风格,通过以上代码我们可以看到apr_前缀,apr_前缀这个符号表示的他在APR的命名范围之内,我们还可以看到_t后缀,他表示他是以数据类型。

apr_pool_t is opaque type. It means the type's structure is not public. By OO(Object Oriented) terminology, all member variables are private. You can't touch them directly. Furthermore, you can't see them in public header files. All you can do for the type is to call APIs such as apr_foo_bar() functions. Most importantly, you can't allocate their instance memories directly. All you can do is to call construct APIs. Only libapr knows how to construct and destruct the objects.

apr_pool_t是一个透明的数据类型,这个数据结构不是公开的,在OO的术语中所有的成员变量都是私有的,我们不能直接访问他,此外我们在公共的头文件中也不能看到他们。我们只能通过类似apr_foo_bar()这个样的API访问这些数据类型,最重要的是我们不能直接的为其事例分配内存空间,我们使用一些构造的API完成这些操作。只有APR本身才知道怎么去创建和销毁这些对象。

As you see, apr_pool_create()'s return type is apr_status_t. apr_status_t is either status code or error code. apr_status_t is a commonly used as return types of most APIs. Accordingly, we can get results from functions by arguments. Such arguments are called result-argument. There are many result-arguments in the libapr world.

 

由上面的代码可见apr_pool_create()返回值是一个apr_status_t类型,apr_status_t既是状态代码也是错误代码。apr_status_t通常被用作APR API的返回值。一次我们可以通过参数的形式得到函数的返回结果。这样的参数我们称之为结果参数(result-argument)。这样获取返回结构的方式APR的世界里很普遍。

In general, if you see apr_foo_t type, you will see apr_foo_bar()
functions, which are related to apr_foo_t type. The following code is a typical
pseudo code.

总之,当你看到apr_foo_t这样的类型,你将看到与之对应的apr_foo_bar()函数,下面的代码是一个典型的范例。

 /* pseudo code of libapr. error checks omitted */
apr_status_t rv;
apr_foo_t *foo;
rv = apr_foo_create(&foo, args...);/* create a @foo object by @args */
rv = apr_foo_do_something(foo, args...); /* do something with @foo */
apr_foo_destroy(foo);
/* destroy the @foo object. Sometimes, this is done implicitly by destroying related memory pool. Please see below */