C中的static function
问题源起
在修改Bitcore 22.0 源码时候碰到的问题,
我们想在每一次收到新块的时候,都能触发一个RPC里的getpeerinfo的调用,因此我找到了src/validation.cpp下的CChainState::UpdateTip函数, 在里面加上了实现在src/rpc/net.cpp的getpeerinfo函数. 但在include "rpc/net.h"后make 出现了下列报错.
但我明明已经include了rpc/net.h, 我本来以为是我include有问题, 修改了半天依然解决不了.
最后我暴力include了一手#include <rpc/net.cpp>,结果发现以下报错:
报错变成了重复定义,这很正常,因为我include的是cpp文件, 所以函数应该在两处都被定义了.
但是我们发现这时候getpeerinfo函数已经可以被编译了, 但是它却没有报重复定义的错误.
我们查看了rpc/net.cpp文件后发现报错的都是其中非static函数, 而所有的static函数都是正常的. static function属于是知识盲区了,以前只知道static method, 因此Google了一手,发现了解答. 简而言之呢就是说static function的作用域只在当前的.c文件下,对于其他文件是不可见的.
因此我们再仔细看了一下bitcore的rpc代码,发现它的rpc使用函数指针的方式进行调用:
void RegisterNetRPCCommands(CRPCTable &t)
{
// clang-format off
static const CRPCCommand commands[] =
{ // category actor
// --------------------- -----------------------
{ "network", &getconnectioncount, },
{ "network", &ping, },
{ "network", &getpeerinfo, },
{ "network", &addnode, },
{ "network", &disconnectnode, },
{ "network", &getaddednodeinfo, },
{ "network", &getnettotals, },
{ "network", &getnetworkinfo, },
{ "network", &setban, },
{ "network", &listbanned, },
{ "network", &clearbanned, },
{ "network", &setnetworkactive, },
{ "network", &getnodeaddresses, },
{ "hidden", &addconnection, },
{ "hidden", &addpeeraddress, },
};
// clang-format on
for (const auto& c : commands) {
t.appendCommand(c.name, &c);
}
}
因此,我们要进行调用的话需要使用它封装好的api而不能直接调用getpeerinfo:
JSONRPCRequest req;
req.context = nullptr;
req.params = nullptr;
req.strMethod = "getpeerinfo";
req.URI = nullptr;
UniValue res = tableRPC.execute(req);
简单复现
写了一个简单的cpp更好的陈述这个问题
test.h
#ifndef TEST_H
#define TEST_H
static void staticprint();
void print();
extern void(*p)() ;
#endif
test.cpp
#include <stdio.h>
static void staticprint(){
printf("static func\n");
}
void print(){
printf("not static func\n");
staticprint();
}
void(*p)() = &staticprint;
main.cpp
#include "test.h"
#include<stdio.h>
int main() {
staticprint();
}
编译会产生如下报错:
把main.cpp改为:
#include "test.h"
#include<stdio.h>
int main() {
//staticprint();
p();
}