使用Variants数组
在VB中,利用Dim语句可以进行Variant数组的编程(www.cppentry.com),并可以使用Array的函数。见如下示例:
Public Sub ArrayOfVariants Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim fld As ADODB.Field
cn.Open "DSN=pubs", "sa", "" rs = cn.OpenSchema(adSchemaColumns, _ Array(Empty, Empty, "authors", Empty)) For Each fld in rs.Fields Debug.Print "Name = "; fld.Name Next fld rs.Close cn.Close End Sub |
以下的代码演示了如何通过一个_variant_t使用一个SafeArray数组。注意注释对应了编码的步骤。
1.再一次的,TESTHR()内置函数被定义以利用预存的错误处理机制。
2.如果你只需要一个一维数组,你可以使用SafeArrayCreateVector,而非SAFEARRAYBOUND声明与SafeArrayCreate函数。下面的代码使用了SafeArrayCreate:
SAFEARRAYBOUND sabound[1]; sabound[0].lLbound = 0; sabound[0].cElements = 4; pSa = SafeArrayCreate(VT_VARIANT, 1, sabound); |
3.枚举常量adSchemaColumns定义的模式,决定了与TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME和COLUMN_NAME四列相联系。为此,一个有四个Variant元素的数组被创建。而对应于第三列TABLE_NAME的值被设置。
由若干列组成的返回的Recordset只是对应的所有列的一个子集,并且每一行的值保持了一一对应。
4.熟悉SafeArrays的人也许会对退出前没有调用SafeArrayDestroy()感到惊奇。实际上,在这种情况下调用SafeArrayDestroy()会导致一个运行时的异常发生。这是因为vtCriteria的析构函数会在_variant_t超出使用范围时调用VariantClear(),从而释放SafeArray。只调用SafeArrayDestroy,而没有手动清除_variant_t,将会导致析构函数试图去清除一个无效的SafeArray指针。如果要调用SafeArrayDestroy(),那么代码应该象这样:
TESTHR(SafeArrayDestroy(pSa)); vtCriteria.vt = VT_EMPTY; vtCriteria.parray = NULL; |
实际更像是让_variant_t管理SafeArray。
完整的代码如下:
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \ no_namespace rename("EOF", "EndOfFile") #include <stdio.h>
// Note 1 inline void TESTHR( HRESULT _hr ) { if FAILED(_hr) _com_issue_error(_hr); }
void main(void) { CoInitialize(NULL); try { _RecordsetPtr pRs("ADODB.Recordset"); _ConnectionPtr pCn("ADODB.Connection"); _variant_t vtTableName("authors"), vtCriteria; long ix[1]; SAFEARRAY *pSa = NULL;
pCn->Open("DSN=pubs;User ID=sa;pwd=;Provider=MSDASQL;", "", "", adConnectUnspecified); // Note 2, Note 3 pSa = SafeArrayCreateVector(VT_VARIANT, 1, 4); if (!pSa) _com_issue_error(E_OUTOFMEMORY);
// 为第三个元素赋值TABLE_NAME(索引值2). ix[0] = 2; TESTHR(SafeArrayPutElement(pSa, ix, &vtTableName));
// 由于Variant没有SafeArray的构造函数,所以手工设置Variant的数据类型和值。 vtCriteria.vt = VT_ARRAY | VT_VARIANT; vtCriteria.parray = pSa;
pRs = pCn->OpenSchema(adSchemaColumns, vtCriteria, vtMissing);
long limit = pRs->GetFields()->Count; for (long x = 0; x < limit; x++) printf("%d: %s\n", x+1, ((char*) pRs->GetFields()->Item[x]->Name)); // Note 4 pRs->Close(); pCn->Close(); } catch (_com_error &e) { printf("Error:\n"); printf("Code = %08lx\n", e.Error()); printf("Code meaning = %s\n", (char*) e.ErrorMessage()); printf("Source = %s\n", (char*) e.Source()); printf("Description = %s\n", (char*) e.Description()); } CoUninitialize(); } |
|