关于 C语言 里的 反射或者内省 的讨论

在语言里面, 根据class名字能够知道其成员的 功能叫做 内省c语言有没有这个功能.

可以想到的办法是 通过宏,你在定义一个结构体的时候,同时生成了一个数据结构存放了这个class的成员名称, 同时, 得到成员的类型, 比如  struct {int a, float b};

通过例子里面的宏可以得到  int a, float b, 这样的字符串的

这个其实已经解决了上次你做 sql数据库函数时想要的功能

对了  今天开会研究nvram的意思就是以后我就不用写那个数据库的东西了?

如果 再得到成员列表字串的时候把类型分立出来, 然后你可以用 "int", sizeof(int); "int", sizeof(float); 这样的东西再做映射, 然后得到一个结构体类型的时候, 即便只有一个指向 class的指针,我们也有办法 把里面的成员一个一个取出来

这样, 对于数据库这样,你每次存的数据结构不同,但是query,什么的这些操作相同的这些操作,完全可以只写一个组函数方法就够了,而不用每
基本上可以达到 动态语言里面的 内省, 反射 的概念了

这个我觉得值得研究, 因为后面不用数据库, 但是对于 nvram这样的存储,你还是会处理各种结构, 但是每种结构到时候的一些操作有是一致的,但是仅仅因为数据类不一样而已

java, c++的这些所谓 ORM 就是依赖于这样的特性才完成的

@table_a
class a {
int    a;
float b;
};

table_new(a);

a a1_obj ;
a1_obj.a = orm_db_query(a.a);

在java 和cpp里面是这样用数据库的

NVRAM 再我看来是 no-sql的非关系型 in-mem 数据库而已

table_new是创建表?

table_new(a); 在java里面用
@table_a
class a {
这样的标签就代替了, 你说多轻松啊

今天下午我们讨论的是 nvram里面放数据怎么弄, 但是从用户接口来说我希望有类似的效果

刚才发给你的文件,里面用宏的方式, 再我们声明一个数据类型的时候就扩展得到了一个类的成员和类型列表

其实对于c来说得到 成员类型名称也白搭,没用,重点是得到  struct a {int , float, char, char *} ,  这样的信息

然后  struct memeber_of_class_size = {
"int", sizeof(int);
"float", sizeof(float);
"char", sizeof(char);
"char *", sizeof(char *);
}
然后直接在 struct的地址上通过加  sizeof(int)这样的东西来知道成员offset
同时也知道了成员的size, 那么就可以做些通用的东西出来了

当然python或者sed或者perl等支持正则的来生成一部分代码也是个办法

以前我们写个结构  struct a { int data; void *(*opt) (void*);} ; 这样的东西每次要  a.opt = a_opt; 来挂载 方法成员, 现在,在刚才的思路上我们一样可以通过宏的方式来实现这个动作

这些库 在c的层面实现了类似的东西, 可以研究下

别人的例子:

#include <stdio.h>
#include <string.h>

#define MEMBER(TYPE,NAME,MORE) TYPE NAME MORE

#define TSTRUCT(NAME,MEMBERS) \
  typedef struct NAME { \
    MEMBERS \
  } NAME; \
  const char* const NAME##_Members = #MEMBERS;

#define PRINT_STRUCT_MEMBERS(NAME) printStructMembers(NAME##_Members)

TSTRUCT(S,
  MEMBER(int,x;,
  MEMBER(void*,z[2];,
  MEMBER(char,(*f)(char,char);,
  MEMBER(char,y;,
  )))));

void printStructMembers(const char* Members)
{
  int level = 0;
  int lastLevel = 0;
  const char* p;
  const char* pLastType = NULL;
  const char* pLastTypeEnd = NULL;

  for (p = Members; *p; p++)
  {
    if (strstr(p, "MEMBER(") == p)
    {
      p += 6; // strlen("MEMBER")
      level++;
      lastLevel = level;
      pLastType = p + 1;
    }
    else if (*p == '(')
    {
      level++;
    }
    else if (*p == ')')
    {
      level--;
    }
    else if (*p == ',')
    {
      if (level == lastLevel)
      {
        if ((pLastType != NULL) && (pLastTypeEnd == NULL))
        {
          pLastTypeEnd = p;
        }
      }
    }
    else if (strstr(p, ";,") == p)
    {
      if ((pLastType != NULL) && (pLastTypeEnd != NULL))
      {
        const char* pp;
        printf("[");
        for (pp = pLastType; pp < pLastTypeEnd; pp++)
          printf("%c", *pp); // print type
        printf("] [");
        for (pp = pLastTypeEnd + 1; pp < p; pp++)
          printf("%c", *pp); // print name
        printf("]\n");
      }
      pLastType = pLastTypeEnd = NULL;
    }
  }
}

char fadd(char a, char b)
{
  return a + b;
}

S s =
{
  1,
  { NULL, NULL },
  &fadd,
  'a'
};

int main(void)
{
  PRINT_STRUCT_MEMBERS(S);
  return 0;
}