这篇文章演示了如何用其他语言(如C,C 或Java)编写的代码插入到Stata中。这种技术被称为Stata编写插件或编写动态链接库(DLL)。本文中,在C语言中编写一个插件,它实现了mymean11.ado中mymean_work()执行的计算,在文章在Stata中编写估计命令编写插件中讨论过。
编写一个hello-world C插件
在进行任何计算之前,先说明如何编写和编译与Stata通信的C插件。Code block 1包含myhello.ado的代码,该代码调用C插件hello,它只显示Stata中的“Hello from C”。
第6行执行句柄hello的插件。第10行将hello.plugin中实现的插件加载到句柄hello中。执行语句在加载语句开始出现之前就是奇数。完整地读取Stata ado文件,并且在执行主要ado程序行之前加载每个ado程序,Mata函数或插件句柄。所以第10行实际上是在第6行之前执行的。
插件的句柄名称,本例中的hello,必须与主要ado程序的名称,本例中的myhello以及此.ado文件中定义的任何其他ado程序不同。
Code block 2中的hello.c的代码。
第2行包括Stata插件页眉文件stplugin.h。第6行是Stata C插件入口函数的标准声明。您应该复制它。在stata_call()中,argc将包含传递给插件的参数数量,字符串向量argv将包含参数本身。
第8行声明并为C字符串msg分配空间。第10行将“Hello from C”中的新行添加到msg中。第11行有Stata显示msg包含的内容。12行将0作为返回码。请注意,我将文字0转换为预期类型ST_retcode。
现在讨论如何从hello.c创建插件hello.plugin。在包含myhello.ado和hello.c的目录中,我也有stplugin.c。stplugin.c定义了一个函数,使stata_call()函数对Stata可用。
不要更改stplugin.h或stplugin.c的内容。事实上,您甚至不需要看它们。
在安装了命令行开发工具的OS X Mac上,使用gcc通过输入stplugin.c和hello.c来创建hello.plugin,
gcc -bundle -DSYSTEM=APPLEMAC stplugin.c hello.c -o hello.plugin
上面的gcc命令编译两个.c文件并链接它们以创建myhello.ado可以调用的DLL hello.plugin。
在本文的附录中,我提供了在其他平台上创建hello.plugin的说明。
创建了hello.plugin后,就可以在Stata中执行myhello。
示例1:myhello
为简单起见,我将stplugin.h,stplugin.c,hello.c,myhello.ado和hello.plugin放在同一目录中。对于较大的项目,我会将.ado和.plugin文件放在Stata的ADOPATH目录中,并使用我的编译器环境来管理我放置标题和C源文件的位置。 对于这篇文章中的示例,我将所有.ado文件,头文件,C源文件和创建的.plugin文件放入一个目录中。
访问插件中的Stata数据
hello.plugin使Stata显示在插件中创建的内容。下一步是让插件访问Stata中的数据。 为了说明这个过程,我讨论了mylistc.ado,它使用插件列出指定变量的观察结果。
我们先来看一下ado-code。
第6行中,syntax创建了三个本地宏。它将用户指定的变量放入本地宏varlist中。它将用户指定的任何if条件放入本地宏if。将用户指定的任何条件放入本地宏in中。为syntax指定了max = 3以将变量数量限制为3。我不需要它作为Stata / Mata程序示例,但它简化了示例C插件。
第7行中,marksample创建了一个样本包含变量,并将其名称放在本地宏touse中。样本包含变量对于每一个被排除的观察和每个被包含的观察都是0。marksample使用本地宏var