• NDArray源码解析及测试代码


    1)NDArray头文件:

    1. #ifndef NDArray_H
    2. #define NDArray_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include "NDAttribute.h"
    8. #include "NDAttributeList.h"
    9. #include "Codec.h"
    10. /** NDArray中维度的最大数目 */
    11. #define ND_ARRAY_MAX_DIMS 10
    12. /** NDArray属性"colorMode"的颜色模式枚举 */
    13. typedef enum
    14. {
    15. NDColorModeMono, /**< 单色 */
    16. NDColorModeBayer, /**< Bayer模式图, 每个像素1个值,但在探测器上带有颜色过滤 */
    17. NDColorModeRGB1, /**< 像素颜色交错的RGB图像, 数据数组是[3, NX, NY] */
    18. NDColorModeRGB2, /**< 行颜色交错的RGB图像 , 数据数组是[NX, 3, NY] */
    19. NDColorModeRGB3, /**< 面颜色交错的RGB图像 , 数据数组是[NX, NY, 3] */
    20. NDColorModeYUV444, /**< YUV 图像, 3字节编码1个RGB像素 */
    21. NDColorModeYUV422, /**< YUV 图像, 4字节编码2个RGB像素 */
    22. NDColorModeYUV411 /**< YUV 图像, 6字节编码4个RGB像素 */
    23. } NDColorMode_t;
    24. /** NDArray属性"bayerPattern"的Bayer颜色枚举. 这个值仅对colorMode是NDColorModeBayer才有意义,
    25. * 因为在读出一个芯片子集时,Bayer模式将变化,所以需要这个值,例如如果X或Y偏移值不是偶数。
    26. */
    27. typedef enum
    28. {
    29. NDBayerRGGB = 0, /**< 第一行RGRG, 第二行GBGB... */
    30. NDBayerGBRG = 1, /**< 第一行GBGB, 第二行RGRG... */
    31. NDBayerGRBG = 2, /**< 第一行GRGR, 第二行BGBG... */
    32. NDBayerBGGR = 3 /**< 第一行BGBG, 第二行GRGR... */
    33. } NDBayerPattern_t;
    34. /** 定义一个NDArray维度的结构体 */
    35. typedef struct NDDimension {
    36. size_t size; /**< 数组的这个维度中元素数目 */
    37. size_t offset; /**< 相对于原始的数据来源(例如,探测器)的原点的偏移量。
    38. * 如果探测器的一个选取区域被读取,则这个值可以大于0.
    39. * 在unbinned像素中和默认方向,非反向中指定这个偏移值,
    40. * 偏移值是累积的,因此如果一个诸如NDPluginROI的插件进一步选取了一个子区域,
    41. * 这个偏移量是相对于探测器中第一个元素,而不是相对于传递给NDPluginROI的区域的第一个元素。
    42. */
    43. int binning; /**< binning(像素求和,1=no binning)相对于原始的数据来源(例如,探测器)
    44. * 偏移值是累积的,因而如果一个诸如NDPluginROI的插件执行binning,
    45. * 相对于探测器中像素而不是相对于传递给NDPluginROI的可能的binned像素表达这个binning。
    46. */
    47. int reverse; /**< 相对于原先的数据来源(例如,探测器)的方向(0=normal,1=reversed)
    48. * 这个值是累积的,因此如果一个诸如NDPluginROI的插件反向这些数据,值必须反映相对于原先探测器的方向,
    49. * 而不是相对于传递给NDPluginROI的可能的反向数据。
    50. */
    51. } NDDimension_t;
    52. /** 由NDArray::getInfo返回的结构体 */
    53. typedef struct NDArrayInfo {
    54. size_t nElements; /**< 数组中元素的总数 */
    55. int bytesPerElement; /**< 数组中每个元素的字节数*/
    56. size_t totalBytes; /**< 保存这个数组所需的字节总数;这可以小于NDArray::dataSize */
    57. /**< 以下对彩色图(RGB1,RGB2,RGB3)最有用 */
    58. NDColorMode_t colorMode; /**< 颜色模式 */
    59. int xDim; /**< 数组索引,它是X维度 */
    60. int yDim; /**< 数组索引,它是Y维度 */
    61. int colorDim; /**< 数组索引,它是颜色维度 */
    62. size_t xSize; /**< 这个数组的X尺寸 */
    63. size_t ySize; /**< 这个数组的Y尺寸 */
    64. size_t colorSize; /**< 这个数组的颜色尺寸 */
    65. size_t xStride; /**< X值之间数组元素的数目 */
    66. size_t yStride; /**< Y值之间数组元素的数目*/
    67. size_t colorStride; /**< 颜色值间数组元素的数目 */
    68. } NDArrayInfo_t;
    69. /**
    70. * N维度数组类;每个数组有一个维度,数据类型,数据指针以及可选的属性的集合。
    71. * 一个数组也有一个标识自身的uniqueId和timeStamp。NDArray对象可以由一个NDArrayPool对象分配,
    72. * 出于内存管理,NDArrayPool对象维护一个NDArrays的空闲列表。
    73. *
    74. */
    75. class ADCORE_API NDArray {
    76. public:
    77. /* 方向 */
    78. NDArray();
    79. NDArray(int ndims, size_t *dims, NDDataType_t dataType, size_t dataSize, void *pData);
    80. virtual ~NDArray();
    81. int initDimension (NDDimension_t *pDimension, size_t size);
    82. static int computeArrayInfo(int ndims, size_t *dims, NDDataType_t dataType, NDArrayInfo *pInfo);
    83. int getInfo (NDArrayInfo_t *pInfo);
    84. int reserve();
    85. int release();
    86. int getReferenceCount() const {return referenceCount;}
    87. int report(FILE *fp, int details);
    88. friend class NDArrayPool;
    89. private:
    90. ELLNODE node; /**< 这必须首先出现,因为ELLNODE必须与NDArray对象有相同地址 */
    91. int referenceCount; /**< 这个NDArray的引用计数,等于正在使用它的客户端数目 */
    92. public:
    93. class NDArrayPool *pNDArrayPool; /**< 创建这个数组的NDArrayPool对象 */
    94. class asynNDArrayDriver *pDriver; /**< 创建这个数组的asynNDArrayDriver*/
    95. int uniqueId; /**< 在一个驱动启动后,由它产生的所有NDArrays中一个必须唯一的编号。*/
    96. double timeStamp; /**< 这个数组以秒为单位的时间戳;推荐从EPICS纪元(00:00:00 UTC, January 1, 1990)的秒数
    97. 但某些驱动可以使用一个不同的起始的时间。*/
    98. epicsTimeStamp epicsTS; /**< epicsTimeStamp,用pasynManager->updateTimeStamp()设置这个变量,并且
    99. 可以来自一个用户定义的时间戳源。 */
    100. int ndims; /**< 这个数组中维度数目,最小=1 */
    101. NDDimension_t dims[ND_ARRAY_MAX_DIMS]; /**< 这个数组的维度尺寸的数组;前ndims个值是有意义 */
    102. NDDataType_t dataType; /**< 这个数组的数据类型 */
    103. size_t dataSize; /**< 这个数组的数据尺寸;为*pData分配的实际内存量,可以多于保存这个数组所需的内存量 */
    104. void *pData; /**< 指向数组数据的指针,认为按dims[0]变化最快,
    105. dims[ndims-1]变化最慢的顺序存储这些数据。 */
    106. NDAttributeList *pAttributeList; /**< 属性的链表 */
    107. Codec_t codec; /**< 用于压缩这些数据的codec定义. */
    108. size_t compressedSize; /**< 压缩数据的尺寸。如果pData未被压缩,应该与dataSize相等。*/
    109. };
    110. /*
    111. 这个类定义了一个被包含在std::multilist中的对象,std::multilist用于排序这个freeList_中的NDArrays
    112. 它定义了一个<操作符,用于使用NDArray::dataSize作为排序键。
    113. 我们想要在NDArrayPool.cpp中隐藏这个类,并且只是在这里先引用了它。
    114. //class sortedListElement;
    115. */
    116. class freeListElement {
    117. public:
    118. freeListElement(NDArray *pArray, size_t dataSize) {
    119. pArray_ = pArray;
    120. dataSize_ = dataSize;}
    121. friend bool operator<(const freeListElement& lhs, const freeListElement& rhs) {
    122. return (lhs.dataSize_ < rhs.dataSize_);
    123. }
    124. NDArray *pArray_;
    125. size_t dataSize_;
    126. private:
    127. freeListElement(); // 默认构造器是私有的,因而对象不能被无参构建
    128. };
    129. /**
    130. * NDArrayPool对象维护一个NDArrays的空闲列表(池)。驱动程序从这个池分配NDArray对象,并且传递这些对象给插件。
    131. * 当插件放置这个NDArray对象到它们的队列时,它们增加对这个对象的索引,而在它们处理完这个数组后,
    132. * 减少对这个对象的索引。当索引计数再次到达0时,这个NDArray对象被放回到空闲列表。
    133. * 这种机制使得在插件中数组的复制最小化。
    134. */
    135. class ADCORE_API NDArrayPool {
    136. public:
    137. NDArrayPool (class asynNDArrayDriver *pDriver, size_t maxMemory);
    138. virtual ~NDArrayPool() {}
    139. NDArray* alloc(int ndims, size_t *dims, NDDataType_t dataType, size_t dataSize, void *pData);
    140. NDArray* copy(NDArray *pIn, NDArray *pOut, bool copyData, bool copyDimensions=true, bool copyDataType=true);
    141. int reserve(NDArray *pArray);
    142. int release(NDArray *pArray);
    143. int convert(NDArray *pIn,
    144. NDArray **ppOut,
    145. NDDataType_t dataTypeOut,
    146. NDDimension_t *outDims);
    147. int convert(NDArray *pIn,
    148. NDArray **ppOut,
    149. NDDataType_t dataTypeOut);
    150. int report(FILE *fp, int details);
    151. int getNumBuffers();
    152. size_t getMaxMemory();
    153. size_t getMemorySize();
    154. int getNumFree();
    155. void emptyFreeList();
    156. protected:
    157. /**
    158. * 应该由管理派生自NDArray类的对象的池类,实现以下方法。
    159. */
    160. virtual NDArray* createArray();
    161. virtual void onAllocateArray(NDArray *pArray);
    162. virtual void onReserveArray(NDArray *pArray);
    163. virtual void onReleaseArray(NDArray *pArray);
    164. private:
    165. std::multiset freeList_;
    166. epicsMutexId listLock_; /**< 保护这个空闲列表 */
    167. int numBuffers_;
    168. size_t maxMemory_; /**< 允许这个对象分配的最大内存字节量; -1=无限*/
    169. size_t memorySize_; /**< 这个对象当前已经分配的内存字节量 */
    170. class asynNDArrayDriver *pDriver_; /**< 创建这个对象的asynNDArrayDriver */
    171. };
    172. #endif

    2)NDArray的实现源文件:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include "NDArray.h"
    8. /** NDArray constructor, no parameters. NDArray构造器,不带参数。
    9. * 初始化所有字段为0,创建属性链表和链表互斥锁。
    10. */
    11. NDArray::NDArray() // referenceCount,pNDArrayPool,pDriver, uniqueId,timeStamp,ndims, dataType(NDInt8),pData
    12. : referenceCount(0), pNDArrayPool(0), pDriver(0),
    13. uniqueId(0), timeStamp(0.0), ndims(0), dataType(NDInt8),
    14. dataSize(0), pData(0)
    15. {
    16. this->epicsTS.secPastEpoch = 0;
    17. this->epicsTS.nsec = 0;
    18. memset(this->dims, 0, sizeof(this->dims)); // dims这个数组中元素全部填0
    19. memset(&this->node, 0, sizeof(this->node)); // ELLNODE node成员结构体填0
    20. this->pAttributeList = new NDAttributeList(); // 一个空的属性链表
    21. }
    22. NDArray::NDArray(int nDims, size_t *dims, NDDataType_t dataType, size_t dataSize, void *pData)
    23. : referenceCount(0), pNDArrayPool(0), pDriver(0),
    24. uniqueId(0), timeStamp(0.0), ndims(nDims), dataType(dataType), // 设置维度数目,每个维度上元素数目,数据类型,数据尺寸未传入值
    25. dataSize(dataSize), pData(0)
    26. {
    27. static const char *functionName = "NDArray::NDArray";
    28. this->epicsTS.secPastEpoch = 0;
    29. this->epicsTS.nsec = 0;
    30. this->pAttributeList = new NDAttributeList();
    31. this->referenceCount = 1;
    32. memset(this->dims, 0, sizeof(this->dims));
    33. for (int i=0; i
    34. this->dims[i].size = dims[i]; // 每一个维度上元素数目
    35. this->dims[i].offset = 0;
    36. this->dims[i].binning = 1;
    37. this->dims[i].reverse = 0;
    38. }
    39. NDArrayInfo arrayInfo;
    40. this->getInfo(&arrayInfo); // 获取数组信息
    41. //如果传入dataSize为0,则根据维度数目,每一维度上的元素数目,以及元素类型计算数据尺寸
    42. if (dataSize == 0) dataSize = arrayInfo.totalBytes;
    43. //
    44. if (arrayInfo.totalBytes > dataSize) {
    45. printf("%s: ERROR: required size=%d passed size=%d is too small\n",
    46. functionName, (int)arrayInfo.totalBytes, (int)dataSize);
    47. }
    48. /* 如果调用这传递了一个有效的缓存,使用这个缓存,相信它的尺寸是正确的 */
    49. if (pData) {
    50. this->pData = pData;
    51. } else {// 如果传递了一个NULL,则分配这个内存空间
    52. this->pData = malloc(dataSize);
    53. this->dataSize = dataSize;
    54. }
    55. }
    56. /** NDArray析构器
    57. * 释放这个数据数组,删除所有属性,释放属性列表并且销毁互斥量
    58. */
    59. NDArray::~NDArray()
    60. {
    61. if (this->pData) free(this->pData);
    62. delete this->pAttributeList;
    63. }
    64. /*
    65. * 便捷方法计算数组中总字节数
    66. typedef struct NDArrayInfo {
    67. size_t nElements; //总元素数目
    68. int bytesPerElement; //每个元素所用字节
    69. size_t totalBytes; //总字节数目
    70. NDColorMode_t colorMode;
    71. int xDim;
    72. int yDim;
    73. int colorDim;
    74. size_t xSize;
    75. size_t ySize;
    76. size_t colorSize;
    77. size_t xStride;
    78. size_t yStride;
    79. size_t colorStride;
    80. } NDArrayInfo_t;
    81. // 根据元素数据类型,维度数目和每一个维度上元素数目
    82. // 获取每个元素字节数,元素总数以及总字节数信息,存入NDArrayInfo结构体
    83. */
    84. int NDArray::computeArrayInfo(int ndims, size_t *dims, NDDataType_t dataType, NDArrayInfo *pInfo)
    85. {
    86. switch(dataType) // 根据指定的元素数据类型,计算每个元素需要的字节数
    87. case NDInt8:
    88. pInfo->bytesPerElement = sizeof(epicsInt8);
    89. break;
    90. case NDUInt8:
    91. pInfo->bytesPerElement = sizeof(epicsUInt8);
    92. break;
    93. case NDInt16:
    94. pInfo->bytesPerElement = sizeof(epicsInt16);
    95. break;
    96. case NDUInt16:
    97. pInfo->bytesPerElement = sizeof(epicsUInt16);
    98. break;
    99. case NDInt32:
    100. pInfo->bytesPerElement = sizeof(epicsInt32);
    101. break;
    102. case NDUInt32:
    103. pInfo->bytesPerElement = sizeof(epicsUInt32);
    104. break;
    105. case NDInt64:
    106. pInfo->bytesPerElement = sizeof(epicsInt64);
    107. break;
    108. case NDUInt64:
    109. pInfo->bytesPerElement = sizeof(epicsUInt64);
    110. break;
    111. case NDFloat32:
    112. pInfo->bytesPerElement = sizeof(epicsFloat32);
    113. break;
    114. case NDFloat64:
    115. pInfo->bytesPerElement = sizeof(epicsFloat64);
    116. break;
    117. default:
    118. return(ND_ERROR);
    119. break;
    120. }
    121. pInfo->nElements = 1;
    122. for (int i=0; inElements *= dims[i]; // 根据维度数目,每个维度上元素数目,计算总元素数目
    123. pInfo->totalBytes = pInfo->nElements * pInfo->bytesPerElement; // 根据每个元素所用字节数和总元素数目计算总字节数目
    124. return ND_SUCCESS;
    125. }
    126. /** 便捷方法:返回有关NDArray的信息;包括这个数组中元素数目,每个元素的字节数目,以及字节总数。
    127. [out] pInfo : 指向一个NDArrayInfo_t结构体的指针,必须已经由调用者分配 .
    128. */
    129. int NDArray::getInfo(NDArrayInfo_t *pInfo)
    130. {
    131. int i;
    132. NDAttribute *pAttribute;
    133. size_t *dims_t = new size_t[this->ndims]; // 根据维度数目分配一个数组
    134. for (i=0; i<this->ndims; i++) dims_t[i] = this->dims[i].size; // 数组中每个元素获取这个NDArray对象中每个维度的尺寸
    135. // 获取每个元素字节数,元素总数以及总字节数信息,存入NDArrayInfo结构体
    136. int status = NDArray::computeArrayInfo(this->ndims, dims_t, this->dataType, pInfo);
    137. delete[] dims_t;
    138. if (status != ND_SUCCESS) return status;
    139. pInfo->colorMode = NDColorModeMono; // 设置颜色模式为单色
    140. pAttribute = this->pAttributeList->find("ColorMode"); // 属性列表中能够找到颜色模式,则设置为获取到的颜色模式
    141. if (pAttribute) pAttribute->getValue(NDAttrInt32, &pInfo->colorMode);
    142. pInfo->xDim = 0;
    143. pInfo->yDim = 0;
    144. pInfo->colorDim = 0;
    145. pInfo->xSize = 0;
    146. pInfo->ySize = 0;
    147. pInfo->colorSize = 0;
    148. pInfo->xStride = 0;
    149. pInfo->yStride = 0;
    150. pInfo->colorStride = 0;
    151. if (this->ndims > 0) {
    152. pInfo->xStride = 1;// X方向是变化最快的维度
    153. pInfo->xSize = this->dims[0].size;
    154. }
    155. if (this->ndims > 1) {
    156. pInfo->yDim = 1; // Y方向是变化其次的维度
    157. pInfo->yStride = pInfo->xSize;
    158. pInfo->ySize = this->dims[1].size;
    159. }
    160. if (this->ndims == 3) {
    161. switch (pInfo->colorMode) {
    162. case NDColorModeRGB1:
    163. pInfo->xDim = 1;
    164. pInfo->yDim = 2;
    165. pInfo->colorDim = 0;
    166. pInfo->xStride = this->dims[0].size;
    167. pInfo->yStride = this->dims[0].size * this->dims[1].size;
    168. pInfo->colorStride = 1;
    169. break;
    170. case NDColorModeRGB2:
    171. pInfo->xDim = 0;
    172. pInfo->yDim = 2;
    173. pInfo->colorDim = 1;
    174. pInfo->xStride = 1;
    175. pInfo->yStride = this->dims[0].size * this->dims[1].size;
    176. pInfo->colorStride = this->dims[0].size;
    177. break;
    178. case NDColorModeRGB3:
    179. pInfo->xDim = 0;
    180. pInfo->yDim = 1;
    181. pInfo->colorDim = 2;
    182. pInfo->xStride = 1;
    183. pInfo->yStride = this->dims[0].size;
    184. pInfo->colorStride = this->dims[0].size * this->dims[1].size;
    185. break;
    186. default:
    187. // This is a 3-D array, but is not RGB
    188. pInfo->xDim = 0;
    189. pInfo->yDim = 1;
    190. pInfo->colorDim = 2;
    191. pInfo->xStride = 1;
    192. pInfo->yStride = this->dims[0].size;
    193. pInfo->colorStride = this->dims[0].size * this->dims[1].size;
    194. break;
    195. }
    196. pInfo->xSize = this->dims[pInfo->xDim].size; //xDim为0
    197. pInfo->ySize = this->dims[pInfo->yDim].size; //yDim为1
    198. pInfo->colorSize = this->dims[pInfo->colorDim].size;
    199. }
    200. return(ND_SUCCESS);
    201. }
    202. /*
    203. 初始化维度结构体NDDimension_t为size=size,binning=1,reverse=0,offset=0。
    204. [in] pDimension : 指向一个NDDimension_t结构体的指针,必须已经由调用者分配.
    205. */
    206. int NDArray::initDimension(NDDimension_t *pDimension, size_t size)
    207. {
    208. pDimension->size=size;
    209. pDimension->binning = 1;
    210. pDimension->offset = 0;
    211. pDimension->reverse = 0;
    212. return ND_SUCCESS;
    213. }
    214. /** 调用这个NDArray对象的NDArrayPool::reserve() ; 为这个数组增加引用计数 . */
    215. int NDArray::reserve()
    216. {
    217. const char *functionName = "NDArray::reserve";
    218. if (!pNDArrayPool) {
    219. printf("%s: WARNING, no owner\n", functionName);
    220. return(ND_ERROR);
    221. }
    222. return(pNDArrayPool->reserve(this));
    223. }
    224. /** 调用这个NDArray对象的NDArrayPool::reverse(); 减小这个数组的引用计数 . */
    225. int NDArray::release()
    226. {
    227. const char *functionName = "NDArray::release";
    228. if (!pNDArrayPool) {
    229. printf("%s: WARNING, no owner\n", functionName);
    230. return(ND_ERROR);
    231. }
    232. return(pNDArrayPool->release(this));
    233. }
    234. /** Reports on the properties of the array. 报告这个数组的性质。
    235. * [in] fp : 用于报告输出的文件指针.
    236. * [in] details: 所需报告详细程度;如果 >5,调用NDAttributeList::report().
    237. */
    238. int NDArray::report(FILE *fp, int details)
    239. {
    240. int dim;
    241. fprintf(fp, "\n");
    242. fprintf(fp, "NDArray Array address=%p:\n", this); // NDArray对象的地址
    243. fprintf(fp, " ndims=%d dims=[", this->ndims); // NDArray对象的维度数目
    244. for (dim=0; dim<this->ndims; dim++) fprintf(fp, "%d ", (int)this->dims[dim].size); // NDArray对象每个维度的元素数目
    245. fprintf(fp, "]\n");
    246. fprintf(fp, " dataType=%d, dataSize=%d, pData=%p\n", // 数据类型,数据尺寸,数据地址
    247. this->dataType, (int)this->dataSize, this->pData);
    248. fprintf(fp, " uniqueId=%d, timeStamp=%f, epicsTS.secPastEpoch=%d, epicsTS.nsec=%d\n", // 唯一id,时间戳
    249. this->uniqueId, this->timeStamp, this->epicsTS.secPastEpoch, this->epicsTS.nsec);
    250. fprintf(fp, " referenceCount=%d\n", this->referenceCount); // 引用计数
    251. fprintf(fp, " number of attributes=%d\n", this->pAttributeList->count()); // 属性数目
    252. if (details > 5) {
    253. this->pAttributeList->report(fp, details); // 每个属性信息
    254. }
    255. return ND_SUCCESS;
    256. }

    3)测试代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include "NDArray.h"
    12. static asynUser * pasynUser = NULL;
    13. int main()
    14. {
    15. int nDims = 2;
    16. size_t dims[2];
    17. size_t dataSize = 0;
    18. epicsTimeStamp currentTime;
    19. //double timeStamp;
    20. dims[0] = 3; dims[1] = 5;
    21. epicsInt32 * pArrs = NULL;
    22. if (!pasynUser){
    23. pasynUser = pasynManager->createAsynUser(0,0);
    24. }
    25. //NDArray * pNDArray = new NDArray(int ndims, size_t *dims, NDDataType_t dataType, size_t dataSize, void *pData);
    26. NDArray * pNDArray = new NDArray(nDims, dims, NDInt32, dataSize, (void *)pArrs) ;
    27. // 获取数组数据的存储地址
    28. pArrs = (epicsInt32 *)pNDArray->pData;
    29. size_t i;
    30. size_t total = dims[0] * dims[1];
    31. // 对NDArray对象的数组赋值
    32. for (i = 0; i < total; i++){
    33. pArrs[i] = i;
    34. }
    35. // 更新timestamp时间戳
    36. pasynManager->updateTimeStamp(pasynUser);
    37. pNDArray->epicsTS = pasynUser->timestamp;
    38. // 更新以秒计的时间戳
    39. epicsTimeGetCurrent(¤tTime);
    40. pNDArray->timeStamp = currentTime.secPastEpoch + currentTime.nsec / 1.e9;
    41. // 调用NDArray对象的report方法 输出这个NDArray对象的信息
    42. pNDArray->report(stdout, 10);
    43. // 输出NDArray数组中的信息:
    44. size_t j;
    45. printf("array data Information:\n");
    46. for (i = 0; i < dims[1]; i++ ){
    47. for (j = 0; j < dims[0]; j++){
    48. printf("%u\t", pArrs[i * dims[0] + j]);
    49. }
    50. printf("\n");
    51. }
    52. NDArrayInfo_t info;
    53. pNDArray->getInfo(&info);
    54. printf("\n");
    55. printf("NDArrayInfo for the NDArray object:\n");
    56. /*
    57. * size_t nElements; //总元素数目
    58. int bytesPerElement; //每个元素所用字节
    59. size_t totalBytes; //总字节数目
    60. NDColorMode_t colorMode;
    61. int xDim;
    62. int yDim;
    63. int colorDim;
    64. size_t xSize;
    65. size_t ySize;
    66. size_t colorSize;
    67. size_t xStride;
    68. size_t yStride;
    69. size_t colorStride;
    70. * */
    71. printf("nElements: %lu,\tbytesPerElement:%d\ttotalBytes: %lu\n", info.nElements, info.bytesPerElement, info.totalBytes);
    72. printf("colorMode: %d\n", info.colorMode);
    73. printf("xDim:%d,\tyDim:%d,\tcolorDim:%d\n", info.xDim, info.yDim, info.colorDim);
    74. printf("xSize:%lu,\tySize:%lu,\tcolorSize:%lu\n", info.xSize, info.ySize, info.colorSize);
    75. printf("xStride:%lu\tyStride:%lu,\tcolorStride:%lu\n", info.xStride, info.yStride, info.colorStride);
    76. delete pNDArray;
    77. return 0;
    78. }

    编译以上源文件进行测试,结果如下:

    1. root@orangepi5:/home/orangepi/C_program/host_program/hostApp# O.linux-aarch64/testNDArray
    2. NDArray Array address=0x55902dda30:
    3. ndims=2 dims=[3 5 ]
    4. dataType=4, dataSize=60, pData=0x55902ddc90
    5. uniqueId=0, timeStamp=1065510588.289565, epicsTS.secPastEpoch=0, epicsTS.nsec=0
    6. referenceCount=1
    7. number of attributes=0
    8. NDAttributeList: address=0x55902ddbd0:
    9. number of attributes=0
    10. array data Information:
    11. 0 1 2
    12. 3 4 5
    13. 6 7 8
    14. 9 10 11
    15. 12 13 14
    16. NDArrayInfo for the NDArray object:
    17. nElements: 15, bytesPerElement:4 totalBytes: 60
    18. colorMode: 0
    19. xDim:0, yDim:1, colorDim:0
    20. xSize:3, ySize:5, colorSize:0
    21. xStride:1 yStride:3, colorStride:0

  • 相关阅读:
    使用舵机和超声波模块实现小车自动避障
    中华黄金·金生态合伙人颁奖典礼在珠海站开幕完美收官!!
    中国交通标志牌数据集TT1OOK中的类别ID及其图标罗列以及含义详细介绍
    完整答题小程序源码/支持流量主/激励广告强点(答题小程序模板+题库)
    【无标题】qml与c++数据交互的一种方式
    【UCIe】UCIe Multi-Module Link 介绍
    使用更灵活、更方便的罗氏线圈
    PostgreSQL 创建数据库、创建用户、赋予权限、创建表、主键总结
    虚拟机Ubuntu
    Centos7 安装 Nginx及启动命令
  • 原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/133640322