记实现TDengine时序数据库支持 .Net Windows 32位系统踩坑

TDengine是一个高效的存储、查询、分析时序大数据的平台,专为物联网、车联网、工业互联网、运维监测等优化而设计的数据库, 官方目前没有提供完整的.Net Core 解决方案, 因此闲来无事, 从基于restful api 到现在使用官方编译的动态库实现Maikebing.EntityFrameworkCore.Taos 一路走来, 对.Net 的Ado.Net 以及EF Core 框架有了深刻了解, 无不感叹 TDengine 的精妙和微软的设计的伟大之处。 

大家知道之前  Maikebing.EntityFrameworkCore.Taos  是不支持 32位的, 现在开始, 以及取得了32位  64位Windows下的支持 以及  Linux64位的支持, 对于32位Windows进展一直不顺利。我们中间遇到了两个问题:

一、查询时总是报访问了保护内存:

System.AccessViolationException:“Attempted to read or write protected memory. This is often an indication that other memory is corrupt.”

 跟官方刘工沟通, 我们将 static extern public int Query (long   taos, string sqlstr); 中的  taos 的类型long改为了 IntPtr , 使用指针的方式进行访问,  各种函数调用是没有问题了。 

二、 32位dll查询结果在 DataReade中从指针中读取 Read32 数据是报错:

一开始只是发现32位dll中, 从指针中用Read32读取整型时报内存错误, 但后面我发现, 只要是第二个字段, 除了主键时间字段外, 其余字段的值似乎都不是正确的值,是在找不到原因, 想想可能是返回结果字段是什么样, 翻到TD源码中 的字段定义, 怀疑这里是不是有问题

        typedef struct taosField

        {

            char name[64];

            short bytes;

            uint8_t type;

        }

但最后发现, 错了, 这里是字段描述, 接下来翻了一下返回结果集中的结构, 那么就待看 taos_fetch_row 方法 是如何实现的,taos_fetch_row 的返回值是  typedef void**  TAOS_ROW; 看到这里, 出于长期从事嵌入式 Linux 下C应用开发的第一直觉, 怀疑可能是 指针长度问题, 因为不同的系统不同的编译器对整型的长度、对内存的对齐是不一样的, 为什么64位成功, 32位不成功, 怀疑问题可能就在这个指针这里, 百度了一下。  确实如此, 因为  TAOS_ROW 返回的是个  二维数组指针, 因此 这个返回结果集中, 32位返回的4字节指针, 64位返回的是 8字节指针, 偏移不一样, 因此我们在  src\Maikebing.Data.Taos\TaosDataReader.cs 的 GetValuePtr中根据进程是否为64位进程来判断便宜, 改代码如下:

   public   IntPtr GetValuePtr(int ordinal)

        {

            object result = DBNull.Value;

            TDengineMeta meta = _metas[ordinal];

            int offset =  (Environment.Is64BitProcess?8:4) * ordinal;

           return  Marshal.ReadIntPtr(rowdata, offset);

        }

同样的方法, 我们修改了   public override object GetValue(int ordinal) 中的 偏移计算方法!完整启动 测试项目, OK, 一切一气呵成。 在这里重申一下, C语言排行榜单又排到第一名, 因此当你熟练C语言之后,在使用其他语言的过程中, 总是有哪些直接会帮助到你。 

Maikebing.EntityFrameworkCore.Taos  现在已经发布了新版本,你可以通过NuGet管理工具安装或者通过下面的命令行之一开安装: 

Install-Package Maikebing.Data.Taos -Version 1.0.53
dotnet add package Maikebing.Data.Taos --version 1.0.53

 对于EF Core 中, 你可以通过下面的命令行来安装至项目:

Install-Package Maikebing.EntityFrameworkCore.Taos -Version 1.0.53
dotnet add package Maikebing.EntityFrameworkCore.Taos --version 1.0.53


GitHub的源码地址:
https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos  

码云的源码地址:
https://gitee.com/maikebing/Maikebing.EntityFrameworkCore.Taos

附在最后:

生活中有人在问, 你为什么会要把自己写的代码公开弄成开源, 写的好了被其他人用, 自己落不到好, 写的不好你不嫌人骂你吗?

我认为既然我从开源社区索取这么多年, 无论工作生活, 开源社区带给我了大量的机会, 从第一份工作, 到第一份北京的工作, 是社区社区给了我机会, 也是社区让我的工作能更好的完成。 因此我觉得无论自己代码写的好坏, 都是希望对其他人有所帮助, 有些项目Fork有很多, 有些项目 无人问津, 我觉得结果并不重要, 而是在于索取和回馈的过程。 

你可能感兴趣的:(记实现TDengine时序数据库支持 .Net Windows 32位系统踩坑)