关于 C 什么是存根例程?一个例子也将不胜感激。
4 回答
存根例程可以是(至少)两件事之一。
首先,它可以是一个占位符例程,您可以快速开发该例程以测试更高级别的例程,以便稍后替换真实版本。这通常与自上而下的开发一起使用(首先编写更高级别的代码,然后再深入了解更详细的内容),并且可以很简单:
int getCount (void) { return 7; } // just return fixed value for testing.
或者稍微复杂一点:
// Cycle through values for some variety.
int getCount (void) {
static int retvals[] = {2,7,1,8,2,8,1,8,2,8,4,5,9};
static int pos = -1;
pos = (pos + 1) % (sizeof (retvals) / sizeof (*retvals));
return retvals[pos];
}
当然,一旦存根变得足够复杂,您也可以只实现真实的东西:-)
其次,它通常用于远程过程调用 (RPC) 环境。存根用于在一端编组数据并将其传送到另一端的服务器。
RPC 需要为客户端和服务器创建存根函数。它与 C 中的函数原型非常相似,但最终结果略有不同,例如:
+----------------+
| Client |
| +----------+ | +---------------+
| | caller | | | Server |
| |----------| | | +----------+ |
| | stub_cli |---- (over the wire) --->| stub_svr | |
| +----------+ | | |----------| |
+----------------+ | | function | |
| +----------+ |
+---------------+
在这个例子中,调用者不是function
在同一个程序中调用,而是调用一个客户端存根函数(具有与 相同的原型function
),该函数负责打包信息并将其通过网络传递到另一个进程。
这可以是同一台机器或不同的机器,这并不重要 - RPC 的优点之一是能够随意移动服务器。
在服务器中,有一个“侦听器”进程将接收该信息并将其传递给服务器。服务器的存根接收信息,将其解包,并将其传递给真正的函数。
真正的函数然后做它需要做的并返回到服务器存根,服务器存根可以打包返回信息并将其传递回客户端存根。
客户端存根然后将其解包并将其传递回调用者。
它是一个与真实函数具有相同签名的函数,但它什么也不做,并且可以像真实的东西一样编译和执行。例如
int MyStub(char * str)
{
/* Stub - Does Nothing */
return 0;
}
这些通常用作占位符,以便可以先制定整体程序结构,然后再制定细节。
在 C 语言中,存根代码实际上调用 main(),而不是操作系统或编译器。
在 C\C++ 中,我们可以在调用另一个函数时将其作为一种安全机制
void stub(void (*func)(int), int arg) {
(*func)(arg);
thread_exit(0);
}
不只是调用的原因func
是要确保一旦运行完成,它就不会返回存储在堆栈顶部的随机值,尤其是在不调用thread_exit(0)
函数的情况下。因此,我们可以返回到 stub,然后调用thread_exit(0)
. func
本身不会调用thread_exit(0)
let stub 来做。