- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在研究几个使用 ADO 访问 SQL Server 数据库的 Visual Studio 2015 C++ 项目类型。简单示例对表执行选择、读入行、更新每一行并更新表。
MFC 版本工作正常。 Windows 控制台版本是我在更新记录集中的行时遇到问题的地方。 update()
记录集的方法抛出一个 COM 异常,错误文本为:
L"Item cannot be found in the collection corresponding to the requested name or ordinal."
HRESULT
的
0x800a0cc1
.
_RecordsetPtr m_pRecordSet; // recordset object
HRESULT CDBrecordset::UpdateRow(const COleVariant vPutFields, COleVariant vValues)
{
m_hr = 0;
if (IsOpened()) {
try {
m_hr = m_pRecordSet->Update(vPutFields, vValues);
}
catch (_com_error &e) {
_bstr_t bstrSource(e.Description());
TCHAR *description;
description = bstrSource;
TRACE2(" _com_error CDBrecordset::UpdateRow %s %s\n", e.ErrorMessage(), description);
m_hr = e.Error();
}
}
if (FAILED(m_hr))
TRACE3(" %S(%d): CDBrecordset::UpdateRow() m_hr = 0x%x\n", __FILE__, __LINE__, m_hr);
return m_hr;
}
COleSafeArray
调用此函数对象组合成一个帮助器类,以便更容易地指定要更新的列名和值。
// Create my connection string and specify the target database in it.
// Then connect to SQL Server and get access to the database for the following actions.
CString ConnectionString;
ConnectionString.Format(pConnectionStringTemp, csDatabaseName);
CDBconnector x;
x.Open(_bstr_t(ConnectionString));
// Create a recordset object so that we can pull the table data that we want.
CDBrecordset y(x);
// ....... open and reading of record set deleted.
MyPluOleVariant thing(2);
thing.PushNameValue (SQLVAR_TOTAL, prRec.lTotal);
thing.PushNameValue (SQLVAR_COUNTER, prRec.lCounter);
hr = y.UpdateRow(thing.saFields, thing.saValues);
CComSafeArray
作为模板。
COleSafeArray
是从
tagVARIANT
派生的类这是一个
union
这是
VARIANT
的数据结构.但是在 ATL COM 中,
CComSafeArray
是我用作
CComSafeArray<VARIANT>
的模板这似乎是合理的。
CDBsafeArray
源自
CComSafeArray<VARIANT>
,我在调用
m_pRecordSet->Update()
时收到以下编译错误:
no suitable user-defined conversion from "const CDBsafeArray" to "const _variant_t" exists
_variant_t
似乎是
VARIANT
的包装类并且在
CComSafeArray<VARIANT>
之间似乎没有转换路径和
_variant_t
但是在
COleSafeArray
之间有一个转换路径和
_variant_t
.
m_psa
SAFEARRAY
类的成员类型
VARIANT
这可以编译,但是我在测试应用程序时看到了上面的 COM 异常。使用调试器查看对象,指定要更新的字段的对象似乎是正确的。
SAFEARRAY
将与
_variant_t
一起使用的包装类?
最佳答案
Microsoft 简要概述 VARIANT
和 SAFEARRAY
VARIANT
type 用于创建一个变量,该变量可能包含许多不同类型的值。这样的变量可以在一个点被分配一个整数值,在另一个点被分配一个字符串值。 ADO 使用 VARIANT
使用许多不同的方法,以便从数据库读取或写入数据库的值可以通过标准接口(interface)提供给调用者,而不是试图拥有许多不同的、特定于数据类型的接口(interface)。
Microsoft 指定了 VARIANT
表示为 C/C++ 的类型 struct
其中包含许多字段。此 struct
的两个主要部分是一个字段,其中包含一个值,该值表示存储在 VARIANT
中的当前值的类型。以及 VARIANT
支持的各种值类型的 union .
除了VARIANT
另一个有用的类型是 SAFEARRAY
.一个 SAFEARRAY
是一个数组,它包含数组管理数据、关于数组的数据,例如它包含多少元素、它的维度以及上限和下限(边界数据允许您具有任意索引范围)。VARIANT
的 C/C++ 源代码看起来像下面这样(所有组件 struct
和 union
成员似乎都是匿名的,例如 __VARIANT_NAME_2
是 #defined
是空的):
typedef struct tagVARIANT VARIANT;
struct tagVARIANT
{
union
{
struct __tagVARIANT
{
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
LONGLONG llVal;
LONG lVal;
BYTE bVal;
SHORT iVal;
// ... lots of other fields in the union
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
} ;
VARIANT
键入 COM 对象接口(interface)以提供通过接口(interface)来回传递数据和执行所需的任何类型的数据转换(编码)的能力。
VARIANT
type 支持多种数据类型,其中之一是
SAFEARAY
.所以你可以使用
VARIANT
通过
SAFEARRAY
通过接口(interface)。而不是明确的
SAFEARRAY
接口(interface),您可以改为指定
VARIANT
将识别和处理
VARIANT
的接口(interface)包含
SAFEARRAY
.
VARIANT
键入其中一些是:
VariantInit()
VariantClear()
VariantCopy()
SAFEARRAY
键入其中一些是:
SafeArrayCreate()
SafeArrayCreateEx()
SafeArrayCopyData();
VARIANT
类:MFC、ATL、 native C++
_variant_t
似乎是
VARIANT
的标准 C++ 类包装器.
_RecordsetPtr
类有
Update()
接受
_variant_t
的方法对象看起来像:
inline HRESULT Recordset15::Update ( const _variant_t & Fields, const _variant_t & Values ) {
HRESULT _hr = raw_Update(Fields, Values);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _hr;
}
VARIANT
的类。类型是
COleVariant
和
COleSafeArray
.如果我们查看这两个类的声明,我们会看到以下内容:
class COleVariant : public tagVARIANT
{
// Constructors
public:
COleVariant();
COleVariant(const VARIANT& varSrc);
// .. the rest of the class declaration
};
class COleSafeArray : public tagVARIANT
{
//Constructors
public:
COleSafeArray();
COleSafeArray(const SAFEARRAY& saSrc, VARTYPE vtSrc);
// .. the rest of the class declaration
};
CComVariant
和
CComSafeArray
然而
CComSafeArray
是一个 C++ 模板。当您使用
CComSafeArray
声明变量时您指定要包含在底层
SAFEARRAY
中的值的类型结构体。声明如下:
class CComVariant : public tagVARIANT
{
// Constructors
public:
CComVariant() throw()
{
// Make sure that variant data are initialized to 0
memset(this, 0, sizeof(tagVARIANT));
::VariantInit(this);
}
// .. other CComVariant class stuff
};
// wrapper for SAFEARRAY. T is type stored (e.g. BSTR, VARIANT, etc.)
template <typename T, VARTYPE _vartype = _ATL_AutomationType<T>::type>
class CComSafeArray
{
public:
// Constructors
CComSafeArray() throw() : m_psa(NULL)
{
}
// create SAFEARRAY where number of elements = ulCount
explicit CComSafeArray(
_In_ ULONG ulCount,
_In_ LONG lLBound = 0) : m_psa(NULL)
{
// .... other CComSafeArray class declaration/definition
};
class _variant_t : public ::tagVARIANT {
public:
// Constructors
//
_variant_t() throw();
_variant_t(const VARIANT& varSrc) ;
_variant_t(const VARIANT* pSrc) ;
// .. other _variant_t class declarations/definition
};
VARIANT
和
SAFEARRAY
.
VARIANT
一起上课
VARIANT
源自
struct tagVARIANT
这允许所有三个可以跨接口(interface)互换使用。不同之处在于每个人如何处理
SAFEARRAY
. MFC 框架提供
COleSafeArray
源自
struct tagVARIANT
并包裹
SAFEARRAY
图书馆。 ATL 框架提供
CComSafeArray
不是源自
struct tagVARIANT
而是使用组合而不是继承。
_variant_t
类有一组构造函数,它们将接受
VARIANT
或指向
VARIANT
的指针以及接受
VARIANT
的赋值和转换操作符方法或指向
VARIANT
的指针.
_variant_t
VARIANT
的方法与 ATL 合作
CComVariant
类和 MFC
COleVariant
和
COleSafeArray
类,因为这些都派生自
struct tagVARIANT
这是
VARIANT
.然而 ATL
CComSafeArray
模板类不适用于
_variant_t
因为它不是从
struct tagVARIANT
继承的.
_variant_t
可以与 ATL 一起使用
CComVariant
或使用 MFC
COleVariant
和
COleSafeArray
但不能与 ATL 一起使用
CComSafeArray
.这样做会产生编译器错误,例如:
no suitable user-defined conversion from "const ATL::CComSafeArray<VARIANT, (VARTYPE)12U>" to "const _variant_t" exists
CComSafeArray
的最简单解决方法似乎是定义一个派生自
CComSafeArray
的类然后提供一个方法来提供
VARIANT
包装
SAFEARRAY
的对象
CComSafeArray
的对象内部
VARIANT
.
struct CDBsafeArray: public CComSafeArray<VARIANT>
{
int m_size;
HRESULT m_hr;
CDBsafeArray(int nSize = 0) : m_size(nSize), m_hr(0)
{
// if a size of number of elements greater than zero specified then
// create the SafeArray which will start out empty.
if (nSize > 0) m_hr = this->Create(nSize);
}
HRESULT CreateOneDim(int nSize)
{
// remember the size specified and create the SAFEARRAY
m_size = nSize;
m_hr = this->Create(nSize);
return m_hr;
}
// create a VARIANT representation of the SAFEARRAY for those
// functions which require a VARIANT rather than a CComSafeArray<VARIANT>.
// this is to provide a copy in a different format and is not a transfer
// of ownership.
VARIANT CreateVariant() const {
VARIANT m_variant = { 0 }; // the function VariantInit() zeros out so just do it.
m_variant.vt = VT_ARRAY | VT_VARIANT; // indicate we are a SAFEARRAY containing VARIANTs
m_variant.parray = this->m_psa; // provide the address of the SAFEARRAY data structure.
return m_variant; // return the created VARIANT containing a SAFEARRAY.
}
};
_RecordsetPtr
Update()
的方法将被称为:
m_hr = m_pRecordSet->Update(saFields.CreateVariant(), saValues.CreateVariant());
关于c++ - _variant_t、COleVariant、CComVariant 和 VARIANT 以及使用 SAFEARRAY 变体之间的用法差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39309122/
最近我在用 RestSharp消耗我的 Restful 资源。并期望在服务器和客户端之间与 JSon 交换数据。下面是我的 C# 代码。 var client = new RestSharp.Rest
我正在阅读 Bartosz Milewski 的一篇文章,其中他定义了以下函数: instance Applicative Chan where pure x = Chan (repeat x)
‘…' 其实是go的一种语法糖。 它的第一个用法主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数。 第二个用法是slice可以被打散进行传递。 实例:
前言 在算face_track_id map有感: 开始验证 data={"state":[1,1,2,2,1,2,2,2],"pop":[&quo
本文实例讲述了php访问数组最后一个元素的函数end()用法。分享给大家供大家参考。具体分析如下: end()函数在PHP中用于检索数组中的最后一个元素。end()函数需要一个数组作为其唯一参数,
我使用的是 jdk1.8.0_92。我的虚拟机如下所示。 $java -version java version "1.8.0_92" Java(TM) SE Runtime Environment
我的情况是我需要将所有匹配 http://mywebsite.com/portfolio/[anyname] 的请求定向到 http://mywebsite.com/portfolio.php?用户名
我正在尝试在 NLTK 中使用语音标记并使用了以下命令: >>> text = nltk.word_tokenize("And now for something completely differe
#include typedef QList IntList; qRegisterMetaType("IntList"); error C2909: 'qRegisterMetaType':
来自 here我知道 BN_CTX 是一个保存 BIGNUM 临时变量的结构。这些 BIGNUM 变量什么时候会进入 BN_CTX 的 BN_POOL?如果我有一个 bignum_ctx BN_CTX
尝试为 ABPersonRef 创建对象例子:ABpersonRef 引用; 已包含Addressbook和AddressBookUI框架即使这样,当我编译时,它仍显示“ABPersonRef”未声明
我无法使用 GetAltTabInfo。可能是一个愚蠢的错误,但这有什么问题呢? HWND taskSwitcher = FindWindow(L"TaskSwitcherWnd", L"Task S
JSLint4Java 是 JSLint 的 Java 包装器。我需要这样的东西在我的 GWT 项目中使用,但使用 JSLint4Java 的唯一方法似乎是从命令行或通过 ANT 任务。有谁知道是否有
我有一个持久化实体对象的方法 persistData() 。我有另一个方法 findData() ,它对同一实体类执行 find() 操作以获取持久的主键值。当我在实体类的@PostPersist中调
下面是我的代码。请查看。 1. bool isUnavailable = db.Deploys.Where(p => p.HostEnvironmentId == Guid.Parse(h
这个问题已经有答案了: Why can't a Generic Type Parameter have a lower bound in Java? (6 个回答) 已关闭 9 年前。 我试图理解为什
我正在尝试使用 scala 编译器 Y 警告,但我认为我做得不对。在下面的示例中,nums 未使用,因此我希望 -Ywarn-value-discard 打印一个警告。有两个 if 条件,一个嵌套在另
用户被要求从某个给定的集合中选择一个 ID。我检查该 ID 是否存在于我的集合中,如果不存在,我会抛出 IndexOutOfBoundsException 并稍后捕获它。我实际上可以使用该异常来达到这
我正在尝试减少从 OSM 路径数据生成的形状文件。我正在使用 VTS 的 DouglasPeuckerSimplifier 实现。我想为特定 GTFS(通用交通提要规范)构建路线图的 geojson。
我明白了?!是排除某个模式,例如 a(?!b) 表示如果“a”后面没有“b”,它将匹配“a”。我的问题是,假设我有一个包含以下内容的文件: a cat is a cat, a dog is a dog
我是一名优秀的程序员,十分优秀!