理解 Visual C++ Extensions for ADO

PyTorch 源码解读之 cpp_extension:讲解 C++/CUDA 算子实现和调用全流程 “Python 用户友好却运行效率低”,“C++ 运行效率较高,但实现一个功能代码量会远大于 Python”。平常学习工作中你是否常听到类似的说法?在 Python 大行其道的今天,你是否经常也会面临代码的瓶颈,而为运行加速而烦恼呢?“我的代码刚跑 10 步,隔壁同学的已经跑完第一个 epoch 了。”--这究竟是人性的扭曲还是科学的沦丧?荀子有言“君子性非异也,善假于物也”。本期《源码解读》带你走进 “Pytorch 中 (神秘) 的 C++ / CUDA 扩展"。 本期主题:结合 Python 与.. 阅读详情

【前言】

当我们使用Visual C++进行ADO编程时,一项颇为头疼的工作就是对VARIANT字段类型的处理。通常做法是,先把VARIANT类型转换为形式上较为类似的C++类型,然后再把转换后的数据存放在一个类(class)或结构(structure)中。即便如此,对VARIANT数据类型的处理在一定程度上也影响到了程序的性能。

ADO为我们提供了一个接口,该接口使我们可以把数据直接读取到本地,从而绕开对于复杂的VARIANT数据类型的处理。同时,ADO还定义了一组预处理宏,用来简化接口的使用。用好这一工具,将会使我们的编程工作将变得轻松和高效。

一般情况下,我们从ADO获得Recordset数据集,然后定义一个C/C++结构类型,再把Recordset中的记录绑定到结构成员变量中。当遇到VARIANT类型时,情况变得复杂,你必须解决如何把VARIANT数据类型(数据库)转换到C/C++数据类型(本地)的问题。Visual C++ Extensions for ADO(为叙述方便,以下简称ADOExt)的目标就是使这一切变得简单。

【IADORecordBinding 接口简介】

ADOExt 把RecordSet记录集中的字段绑定到C/C++变量中。一旦该Recordset当前行的数据发生改变,数据将被立即拷贝到绑定的C/C++变量中。根据需要,数据将被转换到指定的C/C++数据类型。

IADORecordBinding 接口的 BindToRecordset 成员方法用来实现数据库字段到本地C/C++变量之间的绑定。如果要为Recordset新增一条记录,可以使用AddNew方法。Update方法则用来把绑定的C/C++变量数据更新和升级到数据库中。

IADORecordBinding 接口的实现不用我们操心,Recordset对象悄悄的在幕后完成这一切。

【绑定单元(Binding Entries)简介】

ADOExt 把Recordset对象的字段类型映射到本地的C/C++变量中,我们把这种从一个数据库字段映射到一个C/C++变量之间的过程定义称为一个绑定单元(Binding Entries)。绑定由宏来完成,可以绑定的类型包括数值型、定长、以及可变长度的数据。绑定的基本流程是:定义派生自CADORecordBinding(CADORecordBinding 类本身其实也是一组宏定义)的类,在类中使用特定的宏来实现数据绑定。然后,在类中声明相应的C/C++变量。

ADO 在内部把宏定义中的参数映射到一个OLE DB DBBINDING类型的结构中,并且创建一个OLE DB 存取对象用来管理字段和变量之间的数据移动和格式转换。OLE DB 的数据定义包括三个部分:一个用来储存数据的缓冲区;一个用来标示数据存取状态,以及变量如何提取的状态位;以及数据的长度。

【头文件包含】
要使用 Visual C++ 的ADOExt, 你需要在应用程序中包含下列头文件:
#include <icrsint.h>

【绑定Recordset 字段的过程】
■创建一个派生自CADORecordsetBinding的类。

■在派生类中设定绑定单元并定义相应的C/C++变量。这些绑定单元被界定在 BEGIN_ADO_BINDING 和 END_ADO_BINDING 之间。不要想当然的在宏定义间放置逗号或者分号,这些工作会由宏在内部自动实现。

■为每一个要映射为C/C++变量的数据库字段指定一个绑定单元。根据需要从ADO_FIXED_LENGTH_ENTRY, ADO_NUMERIC_ENTRY, 或者 ADO_VARIABLE_LENGTH_ENTRY 这三个宏定义中选择一个,并填写上正确的参数。

■在你的引用程序中,创建一个该类的实例。从 Recordset 中获取 IADORecordBinding 接口。然后调用BindToRecordset方法实现数据绑定。

【接口方法定义】
IADORecordBinding 接口有三个方法:BindToRecordset, AddNew, 以及 Update。这些方法有且只有一个指针类型的参数,该参数指向一个派生自CADORecordBinding的类实例。事实上,AddNew 和 Updage 方法 将分别调用 ADO 中的同名方法。

语法:

BindToRecordset 方法实现 Recordset 字段到 C/C++ 变量之间的绑定。

BindToRecordset(CADORecordBinding *binding)

AddNew 方法调用它的同名方法,ADO 中的 AddNew 方法,向 Recordset 中增加一条新的记录。

AddNew(CADORecordBinding *binding)

Update 方法调用它在ADO中的同名方法 Update, 完成对Recordset的数据更新。

Update(CADORecordBinding *binding)


【理解绑定单元中的宏】
绑定单元定义了Recordset字段和变量之间的联系。 宏BEGIN_ADO_BINDING(Class)(开始宏)和END_ADO_BINDING()(结束宏)界定了一组绑定单元。

绑定单元中的宏提供了对于下列字段类型的支持:
■定长类型的数据。例如 adDate 或 adBoolean
■数值型数据。例如 adTinyInt, adInteger, 以及 adDouble
■变长类型的数据。例如 adChar, adVarChar 以及 adVarBinary

所有的数值型数据,除了 adVarNumeric 类型之外,同时也都是定长类型的数据。

不同的宏定义使用不同类型的参数,这样你就可以排除不感兴趣的绑定信息。

■开始数据绑定

BEGIN_ADO_BINDING(Class)

■定长类型的数据

ADO_FIXED_LENGTH_ENTRY(Ordinal, DataType, Buffer, Status, Modify)
ADO_FIXED_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Modify)

■数值型数据

ADO_NUMERIC_ENTRY(Ordinal, DataType, Buffer, Precision, Scale, Status, Modify)
ADO_NUMERIC_ENTRY2(Ordinal, DataType, Buffer, Precision, Scale, Modify)

■可变长度类型的数据

ADO_VARIABLE_LENGTH_ENTRY(Ordinal, DataType, Buffer, Size, Status, Length, Modify)
ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)
ADO_VARIABLE_LENGTH_ENTRY3(Ordinal, DataType, Buffer, Size, Length,  Modify)
ADO_VARIABLE_LENGTH_ENTRY4(Ordinal, DataType, Buffer, Size, Modify)

■结束数据绑定

END_ADO_BINDING()

---------------------------------------------------
参数:描述

Class:绑定单元和C/C++变量定义所在的类。
Ordinal:序数类型,从1开始计数的Recordset字段序号,该字段对应于指定的C/C++变量。
DataType: 和ADO中的数据类型等价的C/C++数据类型。相应的Recordset字段在需要时将转换为该数据类型。
Buffer:用来存储Recordset字段的缓冲区名称。
Size:缓冲区的最大尺寸。
Status:状态位。指示缓冲区的内容的有效性,以及字段转换是否成功。其中有两个比较重要的值。一个是adFldOK, 表明转换是成功的;另一个是adFldNull, 表明字段值为NULL。更多的状态值,请参考MSDN
Modify:布尔类型。如果为TRUE, 表明ADO允许更新缓冲区中的数据。如果为FALSE,表明数据是只读的。
Precision:数值类型的精度。
Scale:数值类型的小数位数。Number of decimal places in a numeric variable.
Length: 一个四字节的变量。用来包含缓冲区中数据的实际长度。
----------------------------------------------------

【Visual C++ Extensions 例程】
//引入msado15.dll文件,从而声明了ADO类型库
#import "c:/Program Files/Common Files/System/ADO/msado15.dll"  no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <icrsint.h> //在此处包含icrsint.h头文件

//_COM_SMARTPTR_TYPEDEF 宏定义了一个_com_ptr_t类型的智能(smart)指针IADORecordBingingPtr
_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));

//定义一个测试函数
inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }

//定义一个派生自CADORecordBinding的类
class CCustomRs : public CADORecordBinding
{
//开始进行数据类型绑定
BEGIN_ADO_BINDING(CCustomRs)
 //把Recordset的第2个adVarChar类型的字段绑定到C/C++变量m_ch_fname上
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_ch_fname,
                        sizeof(m_ch_fname), m_ul_fnameStatus, false)
   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_ch_lname,
                        sizeof(m_ch_lname), m_ul_lnameStatus, false)
//结束绑定
END_ADO_BINDING()

//紧接着定义上述宏中用到的C/C++变量
public:
   CHAR    m_ch_fname[22];
   CHAR    m_ch_lname[32];
   ULONG   m_ul_fnameStatus;
   ULONG   m_ul_lnameStatus;
};

//开始程序执行
void main(void)
{
   ::CoInitialize(NULL); //初始化COM对象
   try
      {
      //typedef _com_ptr_t<_Recordset, __uuidof(_Recordset)> _RecordsetPtr:指向一个_Recordset的智能指针
      _RecordsetPtr pRs("ADODB.Recordset");
     
      //定义一个CCustomRS: public CADORecordBinding类的实例
      CCustomRs rs;
     
      //把IADORecordBindingPtr接口类型对象picRs指定到pRs对象,从而实现接口和对象之间的关联
      IADORecordBindingPtr picRs(pRs);
     
      //调用_Recordset的Open方法取得Recordset对象
      pRs->Open("SELECT * FROM Employee ORDER BY lname",
         "dsn=pubs;uid=sa;pwd=;",
         adOpenStatic, adLockOptimistic, adCmdText);
     
      //利用CCustomRS类中的宏定义,实现数据之间的绑定
      //如果绑定成功,我们就可以使用rs对象的属性了
      TESTHR(picRs->BindToRecordset(&rs));
   
   //大家注意,这里的EndOfFile对应上文import语句中的rename("EOF", "EndOfFile"),其实就是EOF。rename的作用为了防止命名冲突。
      while (!pRs->EndOfFile)
         {
      // Process data in the CCustomRs C++ instance variables.
         printf("Name = %s %s/n",
            (rs.m_ul_fnameStatus == adFldOK ? rs.m_ch_fname: "<Error>"),
            (rs.m_ul_lnameStatus == adFldOK ? rs.m_ch_lname: "<Error>"));

      // Move to the next row of the Recordset.
      // Fields in the new row will automatically be
      // placed in the CCustomRs C++ instance variables.
  
         pRs->MoveNext();
         }
      }
   catch (_com_error &e )
      {
      printf("Error:/n");
      printf("Code = %08lx/n", e.Error());
      printf("Meaning = %s/n", e.ErrorMessage());
      printf("Source = %s/n", (LPCSTR) e.Source());
      printf("Description = %s/n", (LPCSTR) e.Description());
      }
     
   //清除COM对象实例
   ::CoUninitialize();
}

基于AutoDL复现A-LOAM Ceres solver 是谷歌开发的一款用于非线性优化的库,在谷歌的开源激光雷达slam项目cartographer中被大量使用。在autodl上面租服务器,地区我租的重庆A区的,GPU我选择的是RTX4090,基础镜像选择的是Miniconda / conda3 / 3.8(ubuntu20.04)/11.6。在AutoDL中我使用的方式是先将该数据集先下载到自己的电脑上,然后再上传到虚拟机中。用MobaXterm解决该问题!搜到的一个解决方式:该问题属于ceres版本问题,将A-LOAM下的。 阅读详情

相关推荐

普冉PY32F002B ADC内部参考电压VREFINT的误差补偿与低功耗优化实践

本文详细介绍了普冉PY32F002B单片机在锂电池供电场景下ADC内部参考电压VREFINT的误差补偿与低功耗优化实践。通过分析GPIO配置、分压电阻匹配、采样时间设置等硬件设计要点,结合实时测量VREFINT电压值和软件补偿算法,有效提升了ADC测量精度至5mV以内,并实现了分压电路功耗控制与采样频率优化,为低成本消费电子项目提供了完整的解决方案。

846

.NET Framework 1.0到4.0演进中的真实技术契约与迁移避坑指南

.NET Framework 是 Windows 平台企业级应用的底层运行基石,其核心由 CLR 运行时、BCL 类库和配置模型共同构成。从 1.0 到 4.0 的演进并非简单功能叠加,而是经历了四次底层契约重写:泛型引入重构 JIT 行为、CAS 安全模型确立权限边界、WCF/WPF 等技术整合带来跨组件互操作约束,以及 CLR 4.0 的并行运行时机制。这些变更深刻影响着程序集加载、ViewState 序列化、WCF 配置兼容性与 GAC 版本共存等关键环节。尤其在遗留系统迁移中,.NET Framew

416

体系结构学习-6-超标量处理器

 MIPS32-5段流水线采用了指令级并行方式(5个流水段同时运行5条指令)提升系统吞吐率,是一种标量处理器(CPI≥1CPI \ge 1CPI≥1),但是一个周期一条指令以及无法满足现代计算机需求了。 超标量处理器(Superscalar) 1、基本思想:增强指令集并行,让每个周期执行更多指令,实现 CPI<1CPI<1CPI<1 。(IPC=1/CPIIPC = 1...

qq_40891899的博客 1214

在VC++中使用 Ado 连接到sql server,并 使用insert 语句插入二进制数据

之前在百度找了很久都没有找到利用insert语句插入二进制数据的方法,后来终于是在国外网站上找到了,真是艰辛…… 这里主要是利用 _CommandPtr 对象来添加参数的形式来实现附带二进制数据。 大概的流程就是: 1、把二进制数据封装到 SAFEARRAY 对象中 2、把SAFEARRAY 对象填充到 variant_t 的变量中 3、把 variant_t 变量作为参数的值传入到 C...

humadivinity的博客 1757

lenovo联想拯救者Legion Y9000P 2022款2023款2024款笔记本电脑(82RF,82WK,82WQ,83DE,83DF)原装出厂Windows11预装OEM系统镜像下载

联想原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑管家、联想浏览器、联想软件商店、legionzone控制中心等预装程序。链接:https://pan.baidu.com/s/1YBji_oh7xOkq-NxnS8Mm8g?链接:https://pan.baidu.com/s/1S7_enXmuoja1a9ASvUT5Fg?拯救者Legion Y9000P IRX9H 2024款【83DE】原厂Win11系统包。

QQ17855069的博客 6528

AMG8833红外测温实战:在STM32F103上做个简易人体感应与温度报警器

本文详细介绍了如何在STM32F103上使用AMG8833红外测温传感器构建人体感应与温度报警系统。通过硬件连接方案、驱动代码开发、人体检测算法实现及报警系统设计,展示了如何利用8x8红外温度矩阵实现智能监测功能。文章包含实用的初始化流程、温度数据读取优化和低功耗策略,为创客项目提供完整解决方案。

weixin_33725239的博客 393

什么是 “非标准的 C++ 扩展” (Non-standard C++ extensions) ?

C++ 标准(例如 C++98, C++03, C++11, C++14, C++17, C++20, C++23)由国际标准化组织 (ISO) 的一个工作组 (WG21) 负责制定和维护。理想情况下,所有遵循标准的 C++ 编译器在编译符合标准的代码时,应该产生行为一致的程序。如果你的代码依赖了某个编译器特有的非标准扩展,那么当你想用另一个不同的编译器(或者同一个编译器的不同版本,甚至不同操作系统上的版本)编译这段代码时,很可能会遇到编译错误,因为其他编译器不认识或不支持这些扩展。

抟土成人祖,炼石补青天。眼中览银河,手可摘星辰。 616

jlink驱动安装

jlink驱动下载安装及keil识别

qq_43868701的博客 3万+

c++总结(updating)

c++语法基础

jzw3298364720的博客 2212

Cadence Virtuoso实战:NMOS差分放大器设计与SPICE仿真全解析

本文详细解析了使用Cadence Virtuoso设计NMOS差分放大器并进行SPICE仿真的全流程。从基础设计要点、原理图绘制到工作点分析与性能调优,提供了实用的设计技巧和常见问题解决方案,帮助工程师高效完成模拟集成电路设计。重点介绍了差分放大器的关键参数设置、饱和区优化及版图设计注意事项,适用于ADC、DAC等高性能电路开发。

weixin_28340315的博客 611

R语言caret拟合模型:train函数构建xgBoost Dart模型、模型调优、自定义设置trainControl函数和tuneLength参数

R语言caret拟合模型:train函数构建xgBoost Dart模型、模型调优、自定义设置trainControl函数和tuneLength参数

statistics+insight+vista+power 530

IADORecordBinding

如何使用VC++对ADO的扩展 IADORecordBinding接口 VC++对ADO的扩展联系或绑定了一个Recordset对象的各个字段到C/C++变量。当被绑定的Recordset的当前行改变时,其中所有被绑定的字段的值也同样会被拷贝到相应的C/C++变量中。如果需要,被拷贝的数据还会自动进行相应的数据类型转换。 IADORecordBinding接口的BindToRecords

2220

复数值神经网络可能是深度学习的未来

复数这种东西,在人的头脑中似乎抽象、似乎复杂,然而,对于计算机来说,一点也不抽象,不复杂,那么,将复数概念推广到神经网络会是什么结果呢?本篇介绍国外的一些同行的尝试实践,请我们注意观察他们的进展。

gongdiwudu的专栏 6619

理解 Visual C++ Extensions for ADO(转)

当我们使用Visual C++进行ADO编程时,一项颇为头疼的工作就是对VARIANT字段类型的处理。通常做法是,先把VARIANT类型转换为形式上较为类似的C++类型,然后再把转换后的数据存放在一个类(class)或结构(st...

159

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Visual Studio 2010

在Visual Studio 2010的产品站点上,我们可以了解到VS 2010给我们带来的革新:加强的用户体验:VS2010带来了新用户界面,让工作更专注。便捷的SharePoint开发:对SharePoint开发更完善的支持,让SharePoint开发不再痛苦。应用程序生命周期管理(ALM):把项目角色更紧密地集成到整个应用程序生命周期中。更佳的

瞎掰大数据-- 世界的本质是数据,胡侃瞎掰,专注微软大数据解决方案 814

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C++对C的扩展(Extension)

类型增强 1 类型检查更严格 int num=325; const int* a=&num; // 情况1 int const *a=&num; // 情况2 int* const a=&num; // 情况3 const int* const a=&num; // 情况4 将数据类型去掉,可更直观地查看const修饰谁。 情形1:c

少点套路,多点诚意 3271

.Net-Com双向数据交换的实现(RecordSet与.Net DataSet的转化)

.Net-Com双向数据交换的实现(RecordSet与.Net DataSet的转化) 文前说明:鉴于许多人发Mail询问我关于本文的所涉及的技术问题,由于我无法及时进行一一回复,因此请直接在评论的地方说明即可。另:请转载的人注明出处,以方便其他人能够及时向我反馈问题。谢谢。一:前言 .Net平台的普及和应用为开发人员带来了极大的便利,然而...

weixin_30444105的博客 203

]Visual C++ ODBC数据库编程入门 (2015-06-13 18:06:31)

Visual C++数据库编程       ODBC基本概念   ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分

sunnyli3166的专栏 1364

VC++对ADO的扩展

/////////////////////////////////////////////// VC++对ADO的扩展/////////////////////////////////////////////// 对于VC++程序员而言,每次都要将ADO返回的数据转换成一般的C++数据类型,接着将数据存入一个类或结构总是一件枯燥的事。更讨厌的是这也带来了效率的低下。因此,ADO提供

1410

ADO编程总结

1)引入ADO库定义文件 # import “c:/program files/common files/system/ado/msado15.dll” no_namespace rename (“EOF”,”adoEOF”) 使得编译的时候,为我们的工程文件生成两个头文件: msado15.tlh和ado15.tli 注意,msado15.dll的路径可能有...

316
上一篇: 在WEB项目中多维下拉菜单的实现技巧和方法
下一篇: .NET:是什么?将走向哪里?
tttk
博客等级 码龄27年 37粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值