记实现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有很多, 有些项目 无人问津, 我觉得结果并不重要, 而是在于索取和回馈的过程。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SPDY, WebSocket, WebDAV概念

SPDY(读作“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多…

UDP(发短信:简单模拟)

发短信:不用连接,需要知道对方地址 文章目录UDP发送消息实现互相聊天UDP多线程实现聊天UDP发送消息 UDP传输 我们要用UDP传输数据时,怎么用Socket建立连接呢? DatagramSocket与DatagramPacket 建立发送端,接收端。 建…

SilkierQuartz 1.0.21 发布, 是一个 Quartz.NET 的强大且简单的Web管理工具和承载组件...

SilkierQuartz 是一个新的合并了 Quartzmin 和 QuartzHostedService的组件!Quartz.NET 是一个完整的开源的任务规划系统,从小应用至大型企业级应用都可以适用.Quartzmin Quartzmin 是一个 Quartz.NET 的强大且简单的Web管理工具QuartzHostedService QuartzHostedSer…

超文本运输协议HTTP概念

超文本传输协议(HTTP,HyperTextTransfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。 1960年美国人Ted Nelson构思了一种通过计算机处…

多线程(简单实现)

继承Thread类 两条线程交替进行创建线程方式一:继承Theard类,重写run方法,调用start开启线程总结:注意,线程开启不一定立即执行,由CPU调度执行 //两条线程交替进行//创建线程方式一:继承Theard类&#xf…

用C#在STM32上写第一个Hello world

随着微软放弃.Net MF ,通过C#编写STM32 平台上的程序变得渺茫, 但是, 别着急, 目前至少有两个社区在做这件事情, 传承了微软的.Net MF , 一家是 nanoframework,另外一家比较封闭的是 GHI Electronics 地址是: https://github.com/…

如何找到Eclipse左侧项目栏

如何找到Eclipse左侧项目栏 window --> Show View --> other --> Java–> package Explorer

静态代理模式(多线程底部原理)

静态代理模式总结(线程底部原理) 真实对象和代理对象都要实现同一个接口代理对象要代理真实角色好处: - 代理对象可以做很多真实对象做不了的事情 - 真实对象专注做自己的事情创建静态代理模式:一个接口(当前创建为函数式接口(只…

深入async/await知多少

.net的async/await功能相信对很多人来说并不陌生了,有人感觉这功能很好,但也有人说这功能不好容易产生一些莫名其妙的死锁;有人说这些异步功能也有人说这是同步功能。其实在使用async/await的有多少人真的了解它们呢?接下来详细地…

Java中各种整形类型可以表示的范围

对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下: byte:-128 ~ 127 short: -32768 ~ 32767 int: -214748…

Lambda表达式(多线程实现)

推导lambda表达式 Lambda表达式,避免匿名内部类定义过多,其实质属于函数式编程的概念; 去掉一些没有意义的代码,只留下核心代码; 当前接口为函数式接口(任何一个接口,如果只包含唯一一个抽象方…

微软正式发布 gRPC-Web for .NET

今年一月份的时候,微软曾宣布对 gRPC-Web for .NET 的实验性支持微软实验性地对 .NET 支持 gRPC-Web,现在它已正式发布。gRPC 是谷歌开源的高性能、通用 RPC 框架,支持包括 .NET 在内的多种编程语言。它面向移动和基于 HTTP/2 标准设计&#…

Java多线程(review)

文章目录线程状态线程方法线程停止线程休眠——sleep网络延时模拟倒计时与打印当前系统时间线程礼让——yield线程强制执行——Join线程状态线程优先级守护线程不安全案例死锁Lock锁线程状态 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线…

Java,C++四舍五入

如果要进行四舍五入,可以对浮点数加上0.5再强制转型: package HomeTest01;public class Main {public static void main(String[] args){double a 0.6;System.out.println((int)(a0.5));double b 0.4;System.out.println((int)(b0.5));}}C也同理&…

利用Azure Functions和k8s构建Serverless计算平台

题记:昨晚在一个技术社区直播分享了“利用Azure Functions和k8s构建Serverless计算平台”这一话题。整个分享分为4个部分:Serverless概念的介绍、Azure Functions的简单介绍、k8s和KEDA的介绍和最后的演示。ServerlessServerless其实包含了两种概念&…

Java格式化输出

Java还提供了格式化输出的功能。为什么要格式化输出?因为计算机表示的数据不一定适合人来阅读。 如果要把数据显示成我们期望的格式,就需要使用格式化输出的功能。格式化输出使用System.out.printf(),通过使用占位符%?,printf()…

基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目

系列文章使用 abp cli 搭建项目给项目瘦身,让它跑起来完善与美化,Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API,包装返回模型再说Swagger,分组、描述、小绿锁接入GitHub,用JWT保护你的API异常处理和…

并发协作模型“生产者/消费者模式“

java提供了几个方法解决线程之间的通信问题 方法名作用wait()表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁wait(long timeout)指定等待的毫秒数notify唤醒一个处于等待状态的线程notifyAll()唤醒同一个对象上所有调用wait()方法…

使用线程池

JDk5.0起提供了线程池相关的API:ExecutorService和ExecutorsExectorService:真正的线程池接口。常见的子类ThreadPoolExecutor void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行RunnableFuturesubmit(Calla…

对 JsonConvert 的认识太肤浅了,终于还是遇到了问题

一:背景1. 讲故事在开始本文之前,真的好想做个问卷调查,到底有多少人和我一样,对 JsonConvert 的认识只局限在 SerializeObject 和 DeserializeObject 这两个方法上(┬_┬), 这样我也好结伴同行,不再孤单落…