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

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

  1. #include "stdafx.h"
  2. #include "gdal_priv.h"
  3. #include "cpl_conv.h" // for CPLMalloc()
  4. #include <string>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <iomanip>
  8. #include <boost/cstdint.hpp>
  9.  
  10. using namespace std;
  11.  
  12. void print_line() {
  13. cout << "----------------------" << endl;
  14. }
  15.  
  16. void printDataType(GDALDataType type) {
  17. if (type == GDALDataType::GDT_Byte) {
  18. cout << "GDALDataType: GDT_Byte" << endl;
  19. } else {
  20. cout << "GDALDataType: GDT_Unknown" << endl;
  21. }
  22. }
  23.  
  24. void printAccess(GDALAccess access) {
  25. if (access == GDALAccess::GA_ReadOnly) {
  26. cout << "GDALAccess: GA_ReadOnly" << endl;
  27. } else {
  28. cout << "GDALAccess: GA_Update" << endl;
  29. }
  30. }
  31.  
  32. void printCategoryNames(char** names) {
  33. if (names == NULL) {
  34. cout << "non category names" << endl;
  35. return;
  36. }
  37. size_t i = 0;
  38. char* str = names[i];
  39. while(str != "") {
  40. cout << str << endl;
  41. str = names[i];
  42. }
  43. }
  44.  
  45. void printColorInterp(GDALColorInterp interp) {
  46. switch(interp) {
  47. case GDALColorInterp::GCI_AlphaBand:
  48. cout << "GDALColorInterp: GCI_AlphaBand" << endl;
  49. break;
  50. case GDALColorInterp::GCI_BlackBand:
  51. cout << "GDALColorInterp: GCI_BlackBand" << endl;
  52. break;
  53. case GDALColorInterp::GCI_RedBand:
  54. cout << "GDALColorInterp: GCI_RedBand" << endl;
  55. break;
  56. case GDALColorInterp::GCI_GreenBand:
  57. cout << "GDALColorInterp: GCI_GreenBand" << endl;
  58. break;
  59. case GDALColorInterp::GCI_BlueBand:
  60. cout << "GDALColorInterp: GCI_BlueBand" << endl;
  61. break;
  62. default:
  63. cout << "GDALColorInterp: GCI_Undefined: " << interp << endl;
  64. }
  65. }
  66.  
  67. void printColorTable(GDALColorTable* table) {
  68. if (table == NULL) {
  69. cout << "color table is null" << endl;
  70. return;
  71. }
  72.  
  73. cout << "ColorEntryCount: " << table->GetColorEntryCount() << endl;
  74. }
  75.  
  76. string getBytesAsHexString(uint8_t * data, size_t size) {
  77. stringstream stream;
  78. stream << std::hex << std::uppercase << std::setfill('0');
  79. for (size_t i = 0; i < size; ++i) {
  80. stream <<std::setw(2) << static_cast<uint32_t>(data[i] & 0xff) << " ";
  81. }
  82. return stream.str();
  83. }
  84.  
  85. void printBand(GDALRasterBand* band) {
  86. cout << "XSize: " << band->GetXSize() << endl;
  87. cout << "YSize: " << band->GetYSize() << endl;
  88. cout << "Band number(index for itself): " << band->GetBand() << endl;
  89. printDataType(band->GetRasterDataType());
  90. int x_size = 0;
  91. int y_size = 0;
  92. band->GetBlockSize(&x_size, &y_size);
  93. cout << "Band Block size, x size: " << x_size << " pixels , y size: " << y_size << " pixels" << endl;
  94. printAccess(band->GetAccess());
  95. printCategoryNames(band->GetCategoryNames());
  96. cout << "no data value: " << band->GetNoDataValue() << endl;
  97. cout << "minimum value: " << band->GetMinimum() << endl;
  98. cout << "maximum value: " << band->GetMaximum() << endl;
  99. cout << "offset value: " << band->GetOffset() << endl;
  100. cout << "scale value: " << band->GetScale() << endl;
  101. cout << "unit type: " << band->GetUnitType() << endl;
  102. printColorInterp(band->GetColorInterpretation());
  103. printColorTable(band->GetColorTable());
  104.  
  105. GByte * data = static_cast<GByte*>(CPLMalloc(x_size * y_size));
  106. band->ReadBlock(5000, 3000, data);
  107. cout << "one block data: " << getBytesAsHexString(data, x_size * y_size) << endl;
  108. }
  109.  
  110. void printTiffInfo(GDALDataset* set) {
  111. print_line();
  112. cout << "Tiff info " << endl;
  113. cout << "RasterXSize: " << set->GetRasterXSize() << endl;
  114. cout << "RasterYSize: " << set->GetRasterYSize() << endl;
  115. size_t band_count = set->GetRasterCount();
  116. cout << "Raster band count: " << band_count << endl;
  117. for (size_t i = 1; i <= band_count; ++i) {
  118. GDALRasterBand* band = set->GetRasterBand(i);
  119. print_line();
  120. cout << "Band " << i << " : " << endl;
  121. printBand(band);
  122. }
  123. }
  124.  
  125. int _tmain(int argc, _TCHAR* argv[])
  126. {
  127.  
  128. GDALAllRegister();
  129. string data_dir = "../../../study/data/";
  130. string tiffPath = data_dir + "v4_dem_gtopo30/v4_dem.tif";
  131. GDALDataset* dataset = (GDALDataset *) GDALOpen(tiffPath.c_str(), GA_ReadOnly);
  132. if (dataset == NULL) {
  133. cout << "open ttf file in TiffCopy app failed" << endl;
  134. GDALDestroyDriverManager();
  135. exit(1);
  136. }
  137.  
  138. cout << "loading tiff file successfully" << endl;
  139. printTiffInfo(dataset);
  140.  
  141. GDALClose(dataset);
  142. GDALDestroyDriverManager();
  143. return 0;
  144. }

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

  1. /**
  2. * \brief Close GDAL dataset.
  3. *
  4. * For non-shared datasets (opened with GDALOpen()) the dataset is closed
  5. * using the C++ "delete" operator, recovering all dataset related resources.
  6. * For shared datasets (opened with GDALOpenShared()) the dataset is
  7. * dereferenced, and closed only if the referenced count has dropped below 1.
  8. *
  9. * @param hDS The dataset to close. May be cast from a "GDALDataset *".
  10. */
  11.  
  12. void CPL_STDCALL GDALClose( GDALDatasetH hDS )
  13.  
  14. {
  15. VALIDATE_POINTER0( hDS, "GDALClose" );
  16.  
  17. GDALDataset *poDS = (GDALDataset *) hDS;
  18. CPLMutexHolderD( &hDLMutex );
  19. CPLLocaleC oLocaleForcer;
  20.  
  21. if (poDS->GetShared())
  22. {
  23. /* -------------------------------------------------------------------- */
  24. /* If this file is in the shared dataset list then dereference */
  25. /* it, and only delete/remote it if the reference count has */
  26. /* dropped to zero. */
  27. /* -------------------------------------------------------------------- */
  28. if( poDS->Dereference() > 0 )
  29. return;
  30.  
  31. delete poDS;
  32. return;
  33. }
  34.  
  35. /* -------------------------------------------------------------------- */
  36. /* This is not shared dataset, so directly delete it. */
  37. /* -------------------------------------------------------------------- */
  38. delete poDS;
  39. }

注释表明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. 如何配置Java环境,包括JDK,Maven等

    下载JDK并安装 搜索JDK,官网立马就出来了,下载之后个人觉得毕竟开发,毕竟这东西不大,C盘稳一点,安装在C盘可以的 配置 右键打开计算机->属性->高级系统设置->高级-> ...

  2. 在C#中使用正则表达式筛选出图片URL并下载图片URL中的图片到本地

    本功能主要用到的知识点如下: 1.正则表达式 2.C#中下载文件功能的实现 3.泛型集合的使用 4.进程的简单操作(用于结束当前程序) 下面就简单说一下是如何使用这些知识点的.先详细说下这个程序主要实 ...

  3. CentOS7.5安装网易云音乐

    CentOS7中一直没有一个像样的音乐播放器,网易云音乐与深度科技团队在半年前就启动了“网易云音乐Linux版“, 但是只提供了Ubuntu(14.04&16.04)和deepin15版本,并 ...

  4. tmpfs文件系统

    centos 7测试OK 创建挂载点,挂载 mkdir -p /run/testdirmount -nt tmpfs -o size=500m,mode=755 tmpfs /run/testdir

  5. python中浅拷贝和深度拷贝的区别

    在很多面试题中都会问到浅拷贝跟深度拷贝的区别,前几天一个朋友也问到了我浅拷贝跟深度拷贝到底有什么区别,这里就简单举栗子讲一下两者的区别. 浅拷贝(copy()):拷贝父对象,不会拷贝对象的内部的子对象 ...

  6. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  7. 32、Flask实战第32天:优化json数据的返回

    接着上节,我们通过jsonify返回json数据非常方便 ... return jsonify({"code": 400, "message": message ...

  8. 【DFS】算24点

    [tyvj2802/RQNOJ74]算24点 描述 几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”.您作为游戏者将得到4个1~9之间的自然数作为操作数,而您 ...

  9. 你真的完全了解Java动态代理吗?看这篇就够了

    之前讲了<零基础带你看Spring源码--IOC控制反转>,本来打算下一篇讲讲Srping的AOP的,但是其中会涉及到Java的动态代理,所以先单独一篇来了解下Java的动态代理到底是什么 ...

  10. Problem G: 部分复制字符串

    #include <stdio.h> #include <string.h> int main() { void copystr(char *,char *,int); int ...