C中的对象持久性 [英] Object persistence in C

查看:58
本文介绍了C中的对象持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写软件,以便为磁盘上的任何类型的对象提供一般存储空间。


使用的intermeidate格式是XML,使用模式

(修改了一下)的Microsoft:xmlns =" x-schema:xop-schema.xml"


操作:

----------

该软件生成几个C函数,用于实现XML的写入。为了使事情更具体,假设

以下设置:

typedef struct tagG {

int tab [10];

} Tab;

typedef struct tagstruct {

char a;

short b;

int c;

unsigned d;

long e;

long long f;

long double g;

加倍;

char * str;

标签选项卡;

struct tagstruct *下一步;

}结构;


向导软件生成以下功能:

------------------------------------ ----------

// @结构结构的序列化函数

int structureSerialize(structure * data,FILE * out)

{

int i;

unsigned char * p;

if(data == NULL)

返回0;

if(!initialized){

InitXmlWriter(out);

initialized = 1;

}

fprintf(out,"< Object id = \" ID%x \"

typename = \" structure\ ;> \ n",(int)数据);

fprintf(out," \t< byte name = \" a \">%d< / byte> \ n",data-> a);

fprintf(out," \t< int name = \" b \">%d< / int> \ n",data-> b);

fprintf(out," \t< int name = \" c \">%d< / int> \ n",data-> c);

fprintf(out," \t< unsignedIn t

name = \" d \">%u< / unsignedInt> \ n",data-> d);

fprintf( out," \t< int name = \" e \">%d< / int> \ n",data-> e);

fprintf( out," \t< long name = \" f \">%ll< / long> \ n",data-> f);

//类型为long double本身不支持。

//使用十六进制编码

p =(unsigned char *)& data-> g;

fprintf(out," \t< bin.hex name = \" g\">");

for(i = 0; i< 12; i ++){

fprintf(out,"%x",*(p ++)& 0xff);

}

fprintf(out,"< /bin.hex> \ n");

fprintf(out," \t< double name = \" h\" >%。15g< / double> \ n",data-> h);

//假设char *指向字符串

fprintf(out,

" \t< string name = \" str \" xml:space = \" preserve \">%s< / string> \ n" ,

data-> str);

fprintf(out," \t< IDREF name = \" tab \"> ID% x< / IDREF> \ n",& data-> tab);

fprintf(out," \t< IDREF name = \" Next \"> ; ID%x< / IDREF> \ n",data-> Next);

fprintf(out,"< / Object> \ n");

structureSerialize(data-> Next,out); //按照下一个指针

TabSerialize(& data-> tab,out); //跟随嵌入式结构

返回1;

}

----------------- ------------------------------------------------ <无线电通信/>
调用此函数时将生成以下xml:

------------------------- ---------------------------

< Object id =" ID12ff00" typename =" structure">

< byte name =" a"> -56< / byte>

< int name =" b" > 3876< / int>

< int name =" c"> -254< / int>

< unsignedInt name =" d"> ; 598877< / unsignedInt>

< int name =" e"> 777899< / int>

< bin.hex name =" g"> ; 000000080ff7f00< /bin.hex>

< double name =" h"> 687.988877< / double>

< string name =" str" xml:space =" preserve">字符串< / string>

< IDREF name =" tab"> ID12ff40< / IDREF>

< IDREF name =" Next"> ID0< / IDREF>

< / Object>

--------------- ------------------------------------------


设计原则:

------------------


1)软件将按照指针,应该能够处理

复杂和杂乱的图形,即使它们包含循环。

为此,它记录存储的每个对象的地址。 />
(上面的示例中未显示)

2)由于每个对象的地址都是唯一的,因此实现

不包含嵌入对象,只是引用(指针)

其他对象。所有对象都存储在ObjectStore

标签下(未显示)。


3)公开问题是如何处理:

A)工会。在我看来,没有办法知道工会的哪个

成员是有效的,所以工会将不会被跟踪

并且只是以二进制形式存储。 />
B)函数指针。没有简单的方法可以知道什么是函数指针中存储的函数的名称。

如果加载程序,存储指针可能很有用
在同一地址。


我已经关注了这方面的文献,而且我从来没有看到过任何C实现的b $ b。只是C ++,因为他们必须应对多个遗产层次结构,模板等等,所以问题比C大得多。令人高兴的是C所有内容

更简单。


问题:


你们中任何人都知道一个实现这个在C?


你会对工会和函数指针提出什么建议?


除了
上面提到的那个?


提前感谢您的时间


jacob

I am writing software to make a general storage
facility of any kind of objects to/from disk.

The intermeidate format used is XML, using the schema
(modified a bit) of Microsoft: xmlns="x-schema:xop-schema.xml"

Operation:
----------
The software generates several C functions that implement the
writing of the XML. To make things more concrete suppose
the following setup:

typedef struct tagG {
int tab[10];
} Tab;
typedef struct tagstruct {
char a;
short b;
int c;
unsigned d;
long e;
long long f;
long double g;
double h;
char * str;
Tab tab;
struct tagstruct *Next;
} structure;

The "wizard" software generates the following functions:
----------------------------------------------
//@ Serialization function for structure structure
int structureSerialize(structure *data,FILE *out)
{
int i;
unsigned char *p;
if (data == NULL)
return 0;
if (!initialized) {
InitXmlWriter(out);
initialized=1;
}
fprintf(out,"<Object id=\"ID%x\"
typename=\"structure\">\n",(int)data);
fprintf(out,"\t<byte name=\"a\">%d</byte>\n",data->a);
fprintf(out,"\t<int name=\"b\">%d</int>\n",data->b);
fprintf(out,"\t<int name=\"c\">%d</int>\n",data->c);
fprintf(out,"\t<unsignedInt
name=\"d\">%u</unsignedInt>\n",data->d);
fprintf(out,"\t<int name=\"e\">%d</int>\n",data->e);
fprintf(out,"\t<long name=\"f\">%ll</long>\n",data->f);
// Type long double not supported natively.
// Using hexadecimal encoding
p = (unsigned char *)&data->g;
fprintf(out,"\t<bin.hex name=\"g\">");
for(i=0; i<12;i++) {
fprintf(out,"%x",*(p++) & 0xff);
}
fprintf(out,"</bin.hex>\n");
fprintf(out,"\t<double name=\"h\">%.15g</double>\n",data->h);
// Assume char * points to strings
fprintf(out,
"\t<string name=\"str\" xml:space=\"preserve\">%s</string>\n",
data->str);
fprintf(out,"\t<IDREF name=\"tab\">ID%x</IDREF>\n",&data->tab);
fprintf(out,"\t<IDREF name=\"Next\">ID%x</IDREF>\n",data->Next);
fprintf(out,"</Object>\n");
structureSerialize(data->Next,out); // follow the Next pointer
TabSerialize(&data->tab,out); // Follow embedded structures
return 1;
}
-----------------------------------------------------------------
This function, when called will generate the following xml:
----------------------------------------------------
<Object id="ID12ff00" typename="structure">
<byte name="a">-56</byte>
<int name="b">3876</int>
<int name="c">-254</int>
<unsignedInt name="d">598877</unsignedInt>
<int name="e">777899</int>
<bin.hex name="g">000000080ff7f00</bin.hex>
<double name="h">687.988877</double>
<string name="str" xml:space="preserve">A string</string>
<IDREF name="tab">ID12ff40</IDREF>
<IDREF name="Next">ID0</IDREF>
</Object>
---------------------------------------------------------

Design principles:
------------------

1) The software will follow pointers and should be able to cope with
complicated and messy graphs, even if they contain loops.
To do this it records the address of each object stored.
(Not shown in the example above)
2) Since the address of each object is unique, the implementation
contains no embedded objects, just references (pointers) to
other objects. All objects are stored under the ObjectStore
tag (not shown).

3) Open issues are what to do with:
A) Unions. In my opinion there is no way to know which of the
members of the union is valid, so unions will not be followed
and just stored in binary form.
B) Function pointers. There is no easy way to know what is
the name of the function stored in a function pointer.
Storing the pointer may be useful if the program is loaded
at the same address.

I have followed a bit the literature about this, and I have never
seen any C implementation. Just C++ ones, where the problems are
much bigger than in C since they have to cope with multiple
heritance hierarchies, templates, whatever. Happily in C everything
is much simpler.

Questions:

Are any of you aware of an implementation of this in C?

What would you propose for unions and function pointers?

Are there any other standards for datatypes in XML besides
the one mentioned above?

Thanks in advance for your time

jacob

推荐答案

jacob navia写道:
jacob navia wrote:
我正在编写软件,以便在磁盘上创建任何类型对象的通用存储设备。
I am writing software to make a general storage
facility of any kind of objects to/from disk.




您可以尝试comp.programming,因为他们处理了很多

算法问题。


Jon

----

学习使用Linux汇编语言编程
http://www.cafeshops.com/bartlettpublish.8640017




jacob navia写道:


jacob navia wrote:
我正在编写软件来制作一般存储
任何类型的物体进出磁盘的设施。
[...]
向导软件生成以下功能:
---------------------------------------- ------
// @结构结构的序列化函数
int structureSerialize(结构*数据,文件*输出)
{
int i;
无符号char * p;
if(data == NULL)
返回0;
if(!initialized){
InitXmlWriter(out);
initialized = 1; < br $>


'初始化''是某个静态变量?如果是这样的话,

似乎你只能在

a时间内激活一个XmlWriter流,或者甚至根本没有。


一个可能的替代方案是将FILE *包装在它自己的
a结构中,以及需要的任何状态变量

,这样你就可以做到

XmlWriter * outxml = NewXmlWriter(out);


....然后将XmlWriter *传递给所有向导生成的

(charmed?)函数。

fprintf(out,"< Object id = \" ID%x \"
typename = \" structure\"> \\\
",(int)的数据);


非便携式(我希望你知道),因为指针转换为int的转换是实现定义的,也许是

无意义。即使转换做了一些简单的事情,就像只是复制比特一样。生成的对象ID可能不是唯一的(如果int比指针窄,或者说,或者如果
动态内存管理重新使用free()d对象''内存)。

fprintf(out," \t< byte name = \" a \">%d< / byte> \ n",data-> ; a);
fprintf(out," \t< int name = \" b \">%d< / int> \ n",data-> b);
fprintf(out," \t< int name = \" c \">%d< / int> \ n",data-> c);
...


Bleah。您是否考虑过以表驱动的解决方案?

//本机不支持类型long double。
//使用十六进制编码
p =(unsigned char *)& data- > g;
fprintf(out," \t< bin.hex name = \" g \">");
for(i = 0; i< 12; i ++){
fprintf(out,"%x",*(p ++)& 0xff);
}


非便携式,当然。

structureSerialize(data-> Next,out); //按照下一个指针
TabSerialize(& data-> tab,out); //关注嵌入式结构


我原本预计这些将以相反的顺序完成

(但我没看过M' '软规格)。无论哪种方式,

使用递归追逐可能是一个长链表是

不是一个好主意。

返回1;


如果1表示成功,也许这应该写成

作为'return!ferror(out);'或者其他一些。

3)公开问题是如何处理的:
A)工会。在我看来,没有办法知道工会的哪些成员是有效的,所以工会不会被遵循
并且只是以二进制形式存储。


因此不便携。

B)函数指针。没有简单的方法可以知道什么是函数指针中存储的函数的名称。
如果程序在同一地址加载
,存储指针可能很有用。


...并且还没有被重新编译甚至重新链接,并且

还没有加载更新版本的共享库,

并且没有在调试器下运行...


还有一个问题是C没有定义

将函数指针转换为任何数字数据;

获得便携式表示的唯一方法是使用指针的组成字节来处理


字节流可以被解释但对于除了

之外的收件人而言是相同的程序(如果幸运的话),因此是不可移植的。

如果您有一个可指向的表格功能你可以

将指针转换成一个名字很容易 - 而且这样的

a表在接收端似乎是必要的,以获得

从名称返回到函数指针再次。如果你持有

的函数指针,其目标不在你的表中,

我认为你应该宣布序列化失败。

问题:

你们中的任何人都知道在C中实现这个吗?

您对工会和函数指针的建议是什么?


如果你不能有效地支持他们,不要支持他们

。只有意见; YMMV。

除了上面提到的数据类型之外,还有其他XML数据类型标准吗?
I am writing software to make a general storage
facility of any kind of objects to/from disk.
[...]
The "wizard" software generates the following functions:
----------------------------------------------
//@ Serialization function for structure structure
int structureSerialize(structure *data,FILE *out)
{
int i;
unsigned char *p;
if (data == NULL)
return 0;
if (!initialized) {
InitXmlWriter(out);
initialized=1;
}
Is `initialized'' a static variable somewhere? If so,
it seems you can have only one XmlWriter stream active at
a time, or maybe even at all.

A possible alternative would be to wrap the FILE* in
a struct of its own along with whatever state variables
are needed, so you can do

XmlWriter *outxml = NewXmlWriter(out);

.... and then pass an XmlWriter* to all the wizard-generated
("charmed?") functions.
fprintf(out,"<Object id=\"ID%x\"
typename=\"structure\">\n",(int)data);
Non-portable (as I expect you know), since the conversion
from pointer to int is implementation-defined and perhaps
meaningless. Even if the conversion does something simple
like "just copy the bits," the generated object IDs might
not be unique (if int is narrower than pointer, say, or if
dynamic memory management re-uses a free()d object''s memory).
fprintf(out,"\t<byte name=\"a\">%d</byte>\n",data->a);
fprintf(out,"\t<int name=\"b\">%d</int>\n",data->b);
fprintf(out,"\t<int name=\"c\">%d</int>\n",data->c);
...
Bleah. Have you considered a table-driven solution?
// Type long double not supported natively.
// Using hexadecimal encoding
p = (unsigned char *)&data->g;
fprintf(out,"\t<bin.hex name=\"g\">");
for(i=0; i<12;i++) {
fprintf(out,"%x",*(p++) & 0xff);
}
Non-portable, of course.
structureSerialize(data->Next,out); // follow the Next pointer
TabSerialize(&data->tab,out); // Follow embedded structures
I''d have expected these to be done in the opposite order
(but I haven''t read the M''soft specs). Either way, though,
using recursion to chase what might be a long linked list is
not a wonderful idea.
return 1;
If `1'' means "success," maybe this should be written
as `return !ferror(out);'' or some such.
3) Open issues are what to do with:
A) Unions. In my opinion there is no way to know which of the
members of the union is valid, so unions will not be followed
and just stored in binary form.
Hence non-portable.
B) Function pointers. There is no easy way to know what is
the name of the function stored in a function pointer.
Storing the pointer may be useful if the program is loaded
at the same address.
... and hasn''t been recompiled or even relinked, and
hasn''t been loaded with a newer version of a shared library,
and isn''t running under a debugger and ...

There''s also the problem that C doesn''t define the
conversion of a function pointer to any numeric datum; the
only way to get a portable representation would be to deal
with the pointer''s constituent bytes. The byte stream would
be interpretable by but meaningless to a recipient other than
the same program (if lucky), hence non-portable.

If you have a table of "pointable" functions you can
translate the pointer to a name easily enough -- and such
a table would seem necessary on the receiving end, to get
from name back to function pointer again. If you get hold
of a function pointer whose target is not in your table,
I think you should announce a serialization failure.
Questions:

Are any of you aware of an implementation of this in C?

What would you propose for unions and function pointers?
If you can''t support them usefully, don''t support them
at all. Opinion only; YMMV.
Are there any other standards for datatypes in XML besides
the one mentioned above?




我不是知道。大概。我的反问题:因为你无论如何都要承诺一个不可移植的代表(参见

处理'long double''),为什么要愚弄XML?什么
如果便携包装的内容不是b $ b b b本身便携的话,它会提供优惠吗?


-
Er*********@sun.com


jacob navia写道:
jacob navia wrote:
3)公开问题是如何处理的:
A)工会。在我看来,没有办法知道工会的哪些成员是有效的,所以工会不会被跟踪
而只是以二进制形式存储。
B)函数指针。没有简单的方法可以知道什么是存储在函数指针中的函数的名称。
如果程序在同一地址加载
,存储指针可能很有用。 />你会对工会和函数指针提出什么建议?

jacob
3) Open issues are what to do with:
A) Unions. In my opinion there is no way to know which of the
members of the union is valid, so unions will not be followed
and just stored in binary form.
B) Function pointers. There is no easy way to know what is
the name of the function stored in a function pointer.
Storing the pointer may be useful if the program is loaded
at the same address.
What would you propose for unions and function pointers?

jacob




你可以提供序列化函数来获取union
类型和/或已分配的特定

结构的函数指针,按结构中的外观顺序排列。你可以轻松地通过重载函数来实现这一点,使用你的C编译器和

重载扩展; - >


这个是我会这样做的方式。可能你已经想过了更好的解决方案。


Bahadir



You could provide serialisation functions that take a list of union
types and/or already assigned function pointers for that particular
structure, in order of appeareance in the structure. You could easily
do this by overloading the function, using your C compiler with
overloading extensions ;->

This is the way I would have done it. Probably you have already thought
of better solutions.

Bahadir


这篇关于C中的对象持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆