最近项目的第二个要求便是使用C++对实验采集到的TDMS文件进行读取,从而对数据进行分析以及计算。众所周知,TDMS文件是NI公司提倡的一类文件,关于这个格式的详细介绍大家可以百度,比较关键的一点我简短说一下,该文件内包含几个组,每个组包含几个频道,每个频道中才是采集的数据。
这边文章的主要内容包括具体的代码,以及在使用途中遇到的问题,关于具体的dll的话,可以在NI网站找到,也可以在文章下方留言,我会发送到你的邮箱。
此代码是在NI提供的sample中修改得来,实现了对第一组前四个通道数据的读取,并存入到矩阵中。

具体的代码:在这里插入代码片

#include “nilibddc.h”
#include <stdlib.h>
#include <stdio.h>

using namespace std;
#pragma comment(lib,“nilibddc.lib”)//注意lib的配置

#pragma comment(lib,“user32.lib”)

// Macros
//-----------------------------------------------------------------------------
#define ddcChk(f) if (ddcError = (f), ddcError < 0) goto Error; else
#ifdef nullChk
#undef nullChk
#endif
#define nullChk§ if (!§) { ddcError = DDC_OutOfMemory; goto Error; } else

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static const char * FILE_PATH = “C:\sample.tdms”;

MatrixXd Data;//定义一个矩阵用来接受读入的数据

//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
static int ReadFile (void);
static int ReadGroups (DDCFileHandle file);
static int ReadChannels (DDCChannelGroupHandle group);
double GetAvgDataValue (unsigned __int64 numDataValues, double *data);
void GetDataValue(unsigned __int64 numDataValues, double data,unsigned int j);
//-----------------------------------------------------------------------------
// Program entry-point function
//-----------------------------------------------------------------------------
int main (int argc, char *argv[])
{
int ddcError = 0;

ddcChk (ReadFile());
cout<<Data<<endl;//将矩阵输出

Error:
if (ddcError < 0)
printf ("\nError: %s\n", DDC_GetLibraryErrorDescription(ddcError));
else
printf ("\nNo errors.\n");
printf(“End of program, press Enter key to quit\n”);
getchar();
return 0;
}

//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------

// Reads the file
static int ReadFile (void)
{
int ddcError = 0;
unsigned length;
DDCFileHandle file = 0;
char *property = 0;

// Read file name
ddcChk (DDC_OpenFile (FILE_PATH, "TDMS", &file));
ddcChk (DDC_GetFileStringPropertyLength (file, DDC_FILE_NAME, &length));
nullChk (property =(char*) malloc (length + 1));
ddcChk (DDC_GetFileProperty (file, DDC_FILE_NAME, property, length + 1));printf ("File name property: %s\n", property);
free (property);
property = 0;// Read file description, if present
if (DDC_GetFileStringPropertyLength (file, DDC_FILE_DESCRIPTION, &length) >= 0)
{nullChk (property =(char*) malloc (length + 1));ddcChk (DDC_GetFileProperty (file, DDC_FILE_DESCRIPTION, property, length + 1));printf ("File description property: %s\n", property);free (property); property = 0;
}// Read the channel groups
ddcChk (ReadGroups (file));

Error:
if (property)
free (property);
if (file)
DDC_CloseFile (file);
return ddcError;
}

// Reads all the channel groups in a file
static int ReadGroups (DDCFileHandle file)
{
int ddcError = 0;
unsigned int length;
unsigned int numGroups;
int i;
DDCChannelGroupHandle *groups = 0;
char *property = 0;

// Get all the channel groups
ddcChk (DDC_GetNumChannelGroups (file, &numGroups));
nullChk (groups =(DDCChannelGroupHandle    *)calloc (numGroups, sizeof (DDCChannelGroupHandle)));
ddcChk (DDC_GetChannelGroups (file, groups, numGroups));for(int i=0;i< numGroups;++i)
{// Read the channel group nameddcChk (DDC_GetChannelGroupStringPropertyLength (groups[i], DDC_CHANNELGROUP_NAME, &length));nullChk (property = (char*)malloc (length + 1));ddcChk (DDC_GetChannelGroupProperty (groups[i], DDC_CHANNELGROUP_NAME, property, length + 1));printf ("\n");printf ("Channelgroup #%d name property: %s\n", i+1, property);free (property); property = 0;// Read the channel group description, if presentif (DDC_GetChannelGroupStringPropertyLength (groups[i], DDC_CHANNELGROUP_DESCRIPTION, &length) >= 0){nullChk (property =(char*)malloc (length + 1));ddcChk (DDC_GetChannelGroupProperty (groups[i], DDC_CHANNELGROUP_DESCRIPTION, property, length + 1));printf ("Channelgroup #%d description property: %s\n", i+1, property);free (property); property = 0;}// Read the channels in this groupif(i==0)  //读取第一个group{  ddcChk (ReadChannels (groups[i]));}
}

Error:
// Cleanup
if (groups)
free (groups);
if (property)
free (property);
return ddcError;
}

// Reads all the channels in a channel group
static int ReadChannels (DDCChannelGroupHandle group)
{
int ddcError = 0;
unsigned length;
unsigned int n, numChannels;
unsigned __int64 numDataValues;
DDCChannelHandle *channels = 0;
char *property = 0;
double *data = 0, avgDataValue;

// Read all the channels in this channel group
ddcChk (DDC_GetNumChannels (group, &numChannels));
nullChk (channels =(DDCChannelHandle*)calloc (numChannels, sizeof (DDCChannelHandle)));
ddcChk (DDC_GetChannels (group, channels, numChannels));for (n = 0; n < 4; ++n)    //读取前四个通道
{// Read the channel nameddcChk (DDC_GetChannelStringPropertyLength (channels[n], DDC_CHANNEL_NAME, &length));nullChk (property = (char*)malloc (length + 1));ddcChk (DDC_GetChannelProperty (channels[n], DDC_CHANNEL_NAME, property, length + 1));printf ("\n");printf ("Channel #%d name property: %s\n", n+1, property);free (property); property = 0;// Read the channel description, if presentif (DDC_GetChannelStringPropertyLength (channels[n], DDC_CHANNEL_DESCRIPTION, &length) >= 0){nullChk (property =(char*) malloc (length + 1));ddcChk (DDC_GetChannelProperty (channels[n], DDC_CHANNEL_DESCRIPTION, property, length + 1));printf ("Channel #%d description property: %s\n", n+1, property);free (property); property = 0;}// Read the channel units, if presentif (DDC_GetChannelStringPropertyLength (channels[n], DDC_CHANNEL_UNIT_STRING, &length) >= 0){nullChk (property = (char*)malloc (length + 1));ddcChk (DDC_GetChannelProperty (channels[n], DDC_CHANNEL_UNIT_STRING, property, length + 1));printf ("Channel #%d unit string property: %s\n", n+1, property);free (property); property = 0;}// Read the channel dataddcChk (DDC_GetNumDataValues (channels[n], &numDataValues));nullChk (data = (double*)malloc (sizeof (double) * (unsigned int)numDataValues));ddcChk (DDC_GetDataValues (channels[n], 0, (unsigned int)numDataValues, data));avgDataValue = GetAvgDataValue (numDataValues, data);printf ("Channel #%d number of data values: %I64d\n", n+1, numDataValues);printf ("Channel #%d average data value: %.2f\n", n+1, avgDataValue);GetDataValue(numDataValues,data,&n);//自定函数用来读取数据
}

Error:
// Cleanup
if (data)
free (data);
if (channels)
free (channels);
if (property)
free (property);
return ddcError;
}

double GetAvgDataValue (unsigned __int64 numDataValues, double *data)
{
int j;
double sum = 0.0;

for (j = 0; j < numDataValues; j++)sum += data[j];return sum / (unsigned int)numDataValues;

}
void GetDataValue(unsigned __int64 numDataValues, double data,unsigned int j)
{
for (int m =0; m<numDataValues;m++)
{
Data.resize(numDataValues,4);
int k= *j;
Data(m,k)=data[m];

}
}

注意事项:
首先在配置动态库和头文件时,注意lib的引用,我使用的VS2012,使用64位lib编译会显示无法解析的外部符号,而更换成32位的lib则可以正常编译
其次,注意将TDM C DLL中的 DataModels 文件拷贝到与对应的C++项目中头文件,原文件的同一文件夹下

最后希望大家也能通过我的文章得到一些帮助。

本片文章中的代码大部分来自于NI的sample,不算本人的完全原创。

通过TDM C DLL,使用C实现对TDMS文件的读取相关推荐

  1. netDxf实现对cad文件的读取与写入

    工程项目中CAD作为常用的设计软件 有大量的设计数据及信息需要在项目中使用,cad文件的解析与读取变的十分重要 对cad的解析,尝试过多种方式,java的读文件流 安装dxf的文件格式进行解析,费时又 ...

  2. 朝花夕拾:Java中实现对EXCEL文件的读取

    在项目中实现读取EXCEL文件中的数据是实现工作项目中数据读取的常用方式.这个对于之前无论写C/C++还是后来写Java来读取txt数据的我来说都是一个新的方式.新的技巧,相信对刚入手的很多小伙伴都是 ...

  3. [原创]C#通过引用Office Excel (2007) 组件实现对Excel文件的操作

    对用应用软件来说,将报表转出为Excel文件,进行二次加工,或者根据Excel模版填充数据,是非常常用的.实现对Excel文件的操作,如将报表转出为Excel或根据已有的Excel模版进行填充,有很多 ...

  4. 修改html时webpack热更新,利用webpack实现对html文件的热更新

    webpack中webpack-dev-server是一个简单的web服务器,能够帮助咱们实现代码的热更新,即在实际开发中只需保存修改完后的代码,不用手动刷新页面就能够看到效果.在使用webpack- ...

  5. 使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件)

    使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件) 使用beep播放mp3文件(10num) 使用go语言GUI库fyne实现音乐播放器 要是想使用go语言实现播放mp3需要借助be ...

  6. Qt实现对json文件的解析

    json是一种轻量级的数据结构,其内部的结构是一种键值对(key-value)的组合,最外层是{ }.key是带双引号的字符串常亮,用于获取和存储:value的值可以是bool变量,字符串常量,对象或 ...

  7. python对excel表统计视频教程_Python实现对excel文件列表值进行统计的方法

    本文实例讲述了Python实现对excel文件列表值进行统计的方法.分享给大家供大家参考.具体如下: #!/usr/bin/env python #coding=gbk #此PY用来统计一个execl ...

  8. 用python编excel统计表_Python实现对excel文件列表值进行统计的方法

    本文实例讲述了Python实现对excel文件列表值进行统计的方法.分享给大家供大家参考.具体如下: #!/usr/bin/env python #coding=gbk #此PY用来统计一个execl ...

  9. Java实现对PDF文件添加水印

    Java实现对PDF文件添加水印 目录 Java实现对PDF文件添加水印 导入依赖 工具方法 效果 最近项目中遇到对PDF添加水印,实现有多种,采取的是itextpdf 导入依赖 <!-- 对P ...

最新文章

  1. 创建oracle发邮件job导致的故障
  2. 如何很好的使用Linq的Distinct方法
  3. 转:AIX rcp跨主机远程拷贝数据
  4. 百度工程师控制公司服务器“挖矿”:4个月赚10万 判刑3年
  5. 快速排序算法C#实现
  6. 原生js.ajax内存溢出,javascript - 代码点火器-如何使用jQuery向数据库提交ajax javascript对象 - 堆栈内存溢出...
  7. Python Email发送,通知业务完成
  8. D - 卿学姐与魔法
  9. 我为什么离开德国顶级传统大厂IT部
  10. php hashids思路,使用composer添加hashids加密数字
  11. SQL必知必会 附录解读
  12. win7修复计算机无法修复工具栏,win7任务栏消失怎么办?win7任务栏消失的两种恢复方法...
  13. Android之按钮点击事件(单击、双击、长按等)
  14. 机器学习方法三要素理解:模型、策略、算法
  15. C++实现改变网速*SpeedDuplex和网速监控
  16. 移动数据安全防护措施有哪些
  17. 普及组noip2015年问题求解——重新排列1234和根节点数为2015的二叉树最多有__个叶子节点
  18. healthd log 解读
  19. 红米K30S至尊纪念版和红米K30至尊纪念版哪个好
  20. iOS 内购 payment.applicationUsername 的坑

热门文章

  1. Anaconda环境GDAL库基于whl文件的配置方法
  2. 打分系统 php,jquery做出评分系统
  3. Coggle 30 Days of ML - 糖尿病遗传风险检测挑战赛
  4. 图机器学习(Graph Machine Learning)- 第二章 图机器学习简介 Graph Machine Learning
  5. 8750H带的动MATLAB2019吗,比7820HK略弱 8代酷睿i7-8750H处理器对比7代跑分测试
  6. Convolutional Neural Networks with TensorFlow
  7. 【数字信号处理】:线性调频信号(LFM chirp)产生-复数式余弦式
  8. 笔记本电池常识和THINKPAD电源管理器介绍--能设置充电起点和终点
  9. 微信图灵机器人自动回复和微信加淘宝淘客推广
  10. lenovo 邵阳E42-80 Ubuntu14.04.5 wireless 驱动安装