之前在GDALDestroyDriverManager 分析中没有看到对dGDALDatasert的回收。先看一个例子程序,这个例子打开了一个tif文件,读取了一些基本信息。

为了简单示范,没有写成C++的各种类分散到各个文件中。

#include "stdafx.h"
#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <boost/cstdint.hpp> using namespace std; void print_line() {
cout << "----------------------" << endl;
} void printDataType(GDALDataType type) {
if (type == GDALDataType::GDT_Byte) {
cout << "GDALDataType: GDT_Byte" << endl;
} else {
cout << "GDALDataType: GDT_Unknown" << endl;
}
} void printAccess(GDALAccess access) {
if (access == GDALAccess::GA_ReadOnly) {
cout << "GDALAccess: GA_ReadOnly" << endl;
} else {
cout << "GDALAccess: GA_Update" << endl;
}
} void printCategoryNames(char** names) {
if (names == NULL) {
cout << "non category names" << endl;
return;
}
size_t i = 0;
char* str = names[i];
while(str != "") {
cout << str << endl;
str = names[i];
}
} void printColorInterp(GDALColorInterp interp) {
switch(interp) {
case GDALColorInterp::GCI_AlphaBand:
cout << "GDALColorInterp: GCI_AlphaBand" << endl;
break;
case GDALColorInterp::GCI_BlackBand:
cout << "GDALColorInterp: GCI_BlackBand" << endl;
break;
case GDALColorInterp::GCI_RedBand:
cout << "GDALColorInterp: GCI_RedBand" << endl;
break;
case GDALColorInterp::GCI_GreenBand:
cout << "GDALColorInterp: GCI_GreenBand" << endl;
break;
case GDALColorInterp::GCI_BlueBand:
cout << "GDALColorInterp: GCI_BlueBand" << endl;
break;
default:
cout << "GDALColorInterp: GCI_Undefined: " << interp << endl;
}
} void printColorTable(GDALColorTable* table) {
if (table == NULL) {
cout << "color table is null" << endl;
return;
} cout << "ColorEntryCount: " << table->GetColorEntryCount() << endl;
} string getBytesAsHexString(uint8_t * data, size_t size) {
stringstream stream;
stream << std::hex << std::uppercase << std::setfill('0');
for (size_t i = 0; i < size; ++i) {
stream <<std::setw(2) << static_cast<uint32_t>(data[i] & 0xff) << " ";
}
return stream.str();
} void printBand(GDALRasterBand* band) {
cout << "XSize: " << band->GetXSize() << endl;
cout << "YSize: " << band->GetYSize() << endl;
cout << "Band number(index for itself): " << band->GetBand() << endl;
printDataType(band->GetRasterDataType());
int x_size = 0;
int y_size = 0;
band->GetBlockSize(&x_size, &y_size);
cout << "Band Block size, x size: " << x_size << " pixels , y size: " << y_size << " pixels" << endl;
printAccess(band->GetAccess());
printCategoryNames(band->GetCategoryNames());
cout << "no data value: " << band->GetNoDataValue() << endl;
cout << "minimum value: " << band->GetMinimum() << endl;
cout << "maximum value: " << band->GetMaximum() << endl;
cout << "offset value: " << band->GetOffset() << endl;
cout << "scale value: " << band->GetScale() << endl;
cout << "unit type: " << band->GetUnitType() << endl;
printColorInterp(band->GetColorInterpretation());
printColorTable(band->GetColorTable()); GByte * data = static_cast<GByte*>(CPLMalloc(x_size * y_size));
band->ReadBlock(5000, 3000, data);
cout << "one block data: " << getBytesAsHexString(data, x_size * y_size) << endl;
} void printTiffInfo(GDALDataset* set) {
print_line();
cout << "Tiff info " << endl;
cout << "RasterXSize: " << set->GetRasterXSize() << endl;
cout << "RasterYSize: " << set->GetRasterYSize() << endl;
size_t band_count = set->GetRasterCount();
cout << "Raster band count: " << band_count << endl;
for (size_t i = 1; i <= band_count; ++i) {
GDALRasterBand* band = set->GetRasterBand(i);
print_line();
cout << "Band " << i << " : " << endl;
printBand(band);
}
} int _tmain(int argc, _TCHAR* argv[])
{ GDALAllRegister();
string data_dir = "../../../study/data/";
string tiffPath = data_dir + "v4_dem_gtopo30/v4_dem.tif";
GDALDataset* dataset = (GDALDataset *) GDALOpen(tiffPath.c_str(), GA_ReadOnly);
if (dataset == NULL) {
cout << "open ttf file in TiffCopy app failed" << endl;
GDALDestroyDriverManager();
exit(1);
} cout << "loading tiff file successfully" << endl;
printTiffInfo(dataset); GDALClose(dataset);
GDALDestroyDriverManager();
return 0;
}

在main函数中,用GDALOpen打开了一个tif文件,并且获得了GDALDataset对象的指针,然后用GDALClose销毁了这个对象。下面是GDALClose代码:

/**
* \brief Close GDAL dataset.
*
* For non-shared datasets (opened with GDALOpen()) the dataset is closed
* using the C++ "delete" operator, recovering all dataset related resources.
* For shared datasets (opened with GDALOpenShared()) the dataset is
* dereferenced, and closed only if the referenced count has dropped below 1.
*
* @param hDS The dataset to close. May be cast from a "GDALDataset *".
*/ void CPL_STDCALL GDALClose( GDALDatasetH hDS ) {
VALIDATE_POINTER0( hDS, "GDALClose" ); GDALDataset *poDS = (GDALDataset *) hDS;
CPLMutexHolderD( &hDLMutex );
CPLLocaleC oLocaleForcer; if (poDS->GetShared())
{
/* -------------------------------------------------------------------- */
/* If this file is in the shared dataset list then dereference */
/* it, and only delete/remote it if the reference count has */
/* dropped to zero. */
/* -------------------------------------------------------------------- */
if( poDS->Dereference() > 0 )
return; delete poDS;
return;
} /* -------------------------------------------------------------------- */
/* This is not shared dataset, so directly delete it. */
/* -------------------------------------------------------------------- */
delete poDS;
}

注释表明GDALDataset支持普通和引用计数管理两种生命周期管理方式。代码中表明在销毁的时候使用了互斥量,因此是线程安全的。

GDALDataset的创建和销毁的更多相关文章

  1. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  2. 《Effective Java》—— 创建与销毁对象

    本篇主要总结的是<Effecticve Java>中关于创建和销毁对象的内容. 比如: 何时以及如何创建对象 何时以及如何避免创建对象 如何确保及时销毁 如何管理对象销毁前的清理动作 考虑 ...

  3. ch2 创建和销毁对象

    ch2 创建和销毁对象              

  4. [Effective Java]第二章 创建和销毁对象

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. 《Effect Java》学习笔记1———创建和销毁对象

    第二章 创建和销毁对象 1.考虑用静态工厂方法代替构造器 四大优势: i. 有名称 ii. 不必在每次调用它们的时候都创建一个新的对象:   iii. 可以返回原返回类型的任何子类型的对象: JDBC ...

  6. effective java读书小记(一)创建和销毁对象

    序言 <effective java>可谓是java学习者心中的一本绝对不能不拜读的好书,她对于目标读者(有一点编程基础和开发经验)的人来说,由浅入深,言简意赅.每一章节都分为若干的条目, ...

  7. [ Java学习基础 ] Java对象的创建和销毁

    类实例化可生成对象,实例方法就是对象方法,实例变量就是对象属性.一个对象的生命周期包括三个阶段:创建.使用和销毁. 创建对象 创建对象包括两个步骤:声明和实例化. 声明 声明对象与声明普通变量没有区别 ...

  8. JAVA创建和销毁对象

    类静态方法取代构造方法创建对象 类静态方法有名称,可以通过名称说明返回的是什么类型的实例 可以控制是否需要新开辟内存空间 返回值是可以控制的 实体类属性非常多的时候使用build模式创建对象 单例实体 ...

  9. 和我一起学Effective Java之创建和销毁对象

    前言 主要学习创建和销毁对象: 1.何时以及如何创建对象 2.何时以及如何避免创建对象 3.如何确保它们能够适时地销毁 4.如何管理对象销毁之前必须进行的清理动作 正文 一.用静态工厂方法代替构造器 ...

随机推荐

  1. 兼容python3的SSDB客户端

    SSDB.py import socket class SSDB_Response(object): def __init__(self, code='', data_or_message=None) ...

  2. SnagIt截图后无法在编辑器打开,不显示截图内容的解决办法(转)

    方法1: 用SnagIt截图后,弹出的编辑器里不显示刚才截图的内容,解决办法如下: 完全退出Snagit和编辑器,删除以下文件夹: Win7用户 C:\Users\Administrator\AppD ...

  3. C语言数据类型64位和32机器的区别

    C语言编程需要注意的64位和32机器的区别 .数据类型特别是int相关的类型在不同位数机器的平台下长度不同.C99标准并不规定具体数据类型的长度大小,只规定级别.作下比较: 32位平台 char:1字 ...

  4. ubuntu 18.04下,KMS_6.9.1服务器启动后,客户端连接一段时间因为libnice而crash的问题修复

    相应track issue: https://github.com/Kurento/bugtracker/issues/247 libnice crashes in socket code: g_so ...

  5. 总结分析Java常见的四种引用

    从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 1.强引用 本章前文介绍的引用实际上都是强引用, ...

  6. Bzoj3197/洛谷3296 [SDOI2013]刺客信条assassin(树的重心+树Hash+树形DP+KM)

    题面 Bzoj 洛谷 题解 (除了代码均摘自喻队的博客,可是他退役了) 首先固定一棵树,枚举另一棵树,显然另一棵树只有与这棵树同构才有可能产生贡献 如果固定的树以重心为根,那么另一棵树最多就只有重心为 ...

  7. 【Maven】maven的常用命令以及搭建maven私人仓库

    一.maven环境搭建 1. 二.maven常用命令 1.创建一个新的项目: mvn archetype:create -DgroupId=com.puyangsky.test -DartifactI ...

  8. shell脚本--字符串处理和动态数组

    Linux下的文本处理命令,以清晰的列分割数据为高效处理源: awk 的gsub函数可替换指定字符串 echo "<tr><td>col1</td>< ...

  9. 分布式框架Dubbo配置和实例

    准备工作: 1.ZooKeeper:需要去Apache Zookeeper官网下载Zookeeper.tar.gz包,Dubbo是依赖于Zookeeper的 2.Maven:需要去Apache Mav ...

  10. 【BZOJ 1004】 1004: [HNOI2008]Cards (置换、burnside引理)

    1004: [HNOI2008]Cards Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很 ...