本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API

说明:本篇为归档笔记,内容仍在整理中,后续会继续补充。

简单的说明

作者在本系列的前几期教程中给大家分享了一些编写 GMT 脚本的小技巧,相信大家如果应用得当的话一定能有效提升你的脚本质量。本期教程所涉及的内容并不是 shell 脚本的相关内容,而是关于 GMT 动态库的使用方法。这也是我这几天研究的结果,想给大家粗略地介绍一下,也算给自己留个档。

本篇教程中所使用编程语言为 C/C++,因为也算是预编译脚本吧,姑且就放在这个系列里了。其实 GMT 的接口语言类型很丰富,包括 Matlab、Julia、python 等等,以后有机会再给大家分享这些语言的接口用法。目前,GMT 官方对于其动态库 API 的说明文档还不是很完善,因此很多地方我也是摸着石头过河,不是很清楚,请大家见谅。

本篇教程不涉及动态库的构建讲解,仅从一般使用方法入手。首先我们大致讲解一下 GMT 的 C 语言接口的总体使用策略。

总体策略

一般我们在命令行或者脚本中使用 GMT 命令时,典型的用法如下:

$ gmt grd2cpt example.nc -Rd -Z -D > user.cpt

我们大致可以将这个命令分成这样几个部分:

  1. gmt grd2cpt 指定我们要使用的模块;
  2. example.nc 输入文件;
  3. -Rd -Z -D 模块使用的参数;
  4. user.cpt 输出文件。

其中,2 到 4 可以合并成一项,即某个模块运行需要的一系列参数,其实就是一个字符串。因此,我们首先祭出最核心的一个接口(函数):

int GMT_Call_Module (void *API, const char *module, int mode, void *args);

这个函数一共有 4 个参数,分别为:

  1. void *API GMT 模块调用总接口指针,同一个指针表示同一组调用。一般不用管,除非你在一个程序里要调用多组画图流程;
  2. const char *module 需要调用的模块名称,如 grd2cpt
  3. int mode 调用的模式,一般为 GMT_MODULE_CMD(文后我们会列出可选的类型);
  4. void *args 模块调用使用的参数,如 example.nc -Rd -Z -D > user.cpt

看明白了么?GMT 的 C 语言接口其实非常的强大(傻瓜),我们要做的就是根据我们的数据编写相应模版的参数字符串。例如上面的 grd2cpt 命令从 API 调用就可以写成:

GMT_Call_Module(API, "grd2cpt", GMT_MODULE_CMD, "example.nc -Rd -Z -D ->user.cpt");

注意从 API 调用时,重定向的特殊写法是 ->filename,对应的输入的重定向为 -<filename,追加的重定向写法为 -)filename

因此,我们的所有工作基本就是准备文件,编写参数。然后调用相应的模块就可以了。

虚拟文件

调用 GMT 动态库时可能需要使用一种特殊的虚拟文件。其对象为一个字符串,表示文件的名称。你可以将其理解为是 GMT 的 API 用来管理数据用的标记。典型的用法如下:

GMT_Open_VirtualFile(API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_OUT, NULL, filename);

其中 filename 即为虚拟文件的名称,它的类型必须为 GMT_STR16。其他的参数都是函数调用的选项(文后我们会列出可选的类型)。