X64平台越来越普及,目前一些分析软件多推出了X64版本,而我们的工具集项目同样也有X64版本。我们基于同一套标准C++代码实现了Windows和Linux的跨平台,这几天从X86平台向X64平台迁移的过程中,却遇到了一点麻烦,也学到了一招:(以下内容均限定在wintel+vc 10.0编译器)

假如我有一个类ClassA

class ClassA
{
    ...
    public:
        int search(Filter, void**);
    ...
};

ClassA的1个查询方法(例如空间查询)search接收一个查询过滤器,返回void*数组,在search函数的实现中,采用下面语句:

malloc(sizeof(void*)*count);

好,接下来考虑如下两种调用情形:

long* r_lst1 = NULL;
void* r_lst2 = NULL;
int r1 = ClassAObj->search(flt, r_lst1);
int r2 = ClassAObj->search(flt, r_lst2);

显然,不管什么平台,条件相同的查询得到的结果数量肯定是相同的,也就是有r1==r2;

且在32位平台下,r_lst1与r_lst2将不会有任何区别;

但是在x64平台下,r_lst1在外部显式地声明为long*类型,而long类型在32和64位下均占4个字节,但是在函数实现中采用void*类型申请内存,void*在32位下占4个字节,而在64位平台上占8个字节,这样在外部使用r_lst1[i]形式访问r_lst1中的元素时,就会带来错误。

反过来看第二次查询操作,x64平台下它在外部声明的void*本身为8字节长度,因此不会带来函数内外数据类型字节长度不一致的问题。

因此在这样的一些查询操作中,与其将对象的标识符(通常为整数)作为查询的预期结果元素放入索引结构中,自行在外部处理跨平台问题,不如直接将所操作的对象指针放入索引结构,这样采用void*来进行操作,就避免了数据类型转换带来的字节长度不一致的问题,同时在内存中操作数据也更加便捷,省去了查询到标识符再去取对象数据的过程,可通过直接cast来获得要操作的对象,缺点是查询过程中对象占用内存。

在GIS中需要跨平台(特别是x86+x64)的空间查询优化过程中可考虑该技巧。

 

posted on 2013-05-08 21:31  yeahgis  阅读(629)  评论(0编辑  收藏  举报