ADO.NET Kullanarak Veri Erişimi (C++/CLI)
ADO.NET, veri erişimi için .NET Framework API'dir ve önceki veri erişim çözümleriyle eşleşmeyen güç ve kullanım kolaylığı sağlar. Bu bölümde, yerel türleri hazırlama gibi Visual C++ kullanıcılarına özgü ADO.NET ile ilgili bazı sorunlar açıklanmaktadır.
ADO.NET Ortak Dil Çalışma Zamanı (CLR) altında çalışır. Bu nedenle, ADO.NET ile etkileşim kuran tüm uygulamalar da CLR'yi hedeflemelidir. Ancak bu, yerel uygulamaların ADO.NET kullanamayacağı anlamına gelmez. Bu örnekler, yerel koddan bir ADO.NET veritabanıyla nasıl etkileşim kurulacağını gösterir.
ansi dizelerini ADO.NET için hazırlama
Veritabanına yerel dize (char *
) eklemeyi ve veritabanından yerel dizeye nasıl sıralamayı System.String gösterir.
Örnek
Bu örnekte DatabaseClass sınıfı bir ADO.NET DataTable nesnesiyle etkileşim kurmak için oluşturulmuştur. Bu sınıfın yerel bir C++ class
olduğunu unutmayın (veya value class
ile karşılaştırıldığındaref class
). Bu sınıfı yerel koddan kullanmak istediğimiz ve yönetilen türleri yerel kodda kullanamayacağınız için bu gereklidir. Bu sınıf, sınıf bildiriminden önceki yönerge tarafından gösterildiği gibi CLR'yi #pragma managed
hedeflemek için derlenir. Bu yönerge hakkında daha fazla bilgi için bkz . yönetilen, yönetilmeyen.
DatabaseClass sınıfının özel üyesine dikkat edin: gcroot<DataTable ^> table
. Yerel türler yönetilen türler içeremediğinden gcroot
anahtar sözcüğü gereklidir. hakkında gcroot
daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Bu örnekteki kodun geri kalanı yerel C++ kodudur ve önceki main
yönergesinde #pragma unmanaged
de belirtilmiştir. Bu örnekte, yeni bir DatabaseClass örneği oluşturup tablo oluşturmak ve tablodaki bazı satırları doldurmak için yöntemlerini çağırıyoruz. Yerel C++ dizelerinin StringCol veritabanı sütunu için değer olarak geçirildiğini unutmayın. DatabaseClass içinde, bu dizeler ad alanında System.Runtime.InteropServices bulunan sıralama işlevselliği kullanılarak yönetilen dizelere sıralanır. Özellikle, yöntemi PtrToStringAnsi için bir char *
sıralamak için Stringkullanılır ve yöntemi StringToHGlobalAnsi bir için sıralamak String için char *
kullanılır.
Not
tarafından StringToHGlobalAnsi ayrılan bellek veya GlobalFree
çağrılarak FreeHGlobal serbest bırakılmalıdır.
// adonet_marshal_string_native.cpp
// compile with: /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll
#include <comdef.h>
#include <gcroot.h>
#include <iostream>
using namespace std;
#using <System.Data.dll>
using namespace System;
using namespace System::Data;
using namespace System::Runtime::InteropServices;
#define MAXCOLS 100
#pragma managed
class DatabaseClass
{
public:
DatabaseClass() : table(nullptr) { }
void AddRow(char *stringColValue)
{
// Add a row to the table.
DataRow ^row = table->NewRow();
row["StringCol"] = Marshal::PtrToStringAnsi(
(IntPtr)stringColValue);
table->Rows->Add(row);
}
void CreateAndPopulateTable()
{
// Create a simple DataTable.
table = gcnew DataTable("SampleTable");
// Add a column of type String to the table.
DataColumn ^column1 = gcnew DataColumn("StringCol",
Type::GetType("System.String"));
table->Columns->Add(column1);
}
int GetValuesForColumn(char *dataColumn, char **values,
int valuesLength)
{
// Marshal the name of the column to a managed
// String.
String ^columnStr = Marshal::PtrToStringAnsi(
(IntPtr)dataColumn);
// Get all rows in the table.
array<DataRow ^> ^rows = table->Select();
int len = rows->Length;
len = (len > valuesLength) ? valuesLength : len;
for (int i = 0; i < len; i++)
{
// Marshal each column value from a managed string
// to a char *.
values[i] = (char *)Marshal::StringToHGlobalAnsi(
(String ^)rows[i][columnStr]).ToPointer();
}
return len;
}
private:
// Using gcroot, you can use a managed type in
// a native class.
gcroot<DataTable ^> table;
};
#pragma unmanaged
int main()
{
// Create a table and add a few rows to it.
DatabaseClass *db = new DatabaseClass();
db->CreateAndPopulateTable();
db->AddRow("This is string 1.");
db->AddRow("This is string 2.");
// Now retrieve the rows and display their contents.
char *values[MAXCOLS];
int len = db->GetValuesForColumn(
"StringCol", values, MAXCOLS);
for (int i = 0; i < len; i++)
{
cout << "StringCol: " << values[i] << endl;
// Deallocate the memory allocated using
// Marshal::StringToHGlobalAnsi.
GlobalFree(values[i]);
}
delete db;
return 0;
}
StringCol: This is string 1.
StringCol: This is string 2.
Kod Derleniyor
Kodu komut satırından derlemek için kod örneğini adonet_marshal_string_native.cpp adlı bir dosyaya kaydedin ve aşağıdaki deyimi girin:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
ADO.NET için BSTR Dizelerini Hazırlama
Veritabanına COM dizesi (BSTR
) eklemeyi ve veritabanından 'a sıralamayı System.String BSTR
gösterir.
Örnek
Bu örnekte DatabaseClass sınıfı bir ADO.NET DataTable nesnesiyle etkileşim kurmak için oluşturulmuştur. Bu sınıfın yerel bir C++ class
olduğunu unutmayın (veya value class
ile karşılaştırıldığındaref class
). Bu sınıfı yerel koddan kullanmak istediğimiz ve yönetilen türleri yerel kodda kullanamayacağınız için bu gereklidir. Bu sınıf, sınıf bildiriminden önceki yönerge tarafından gösterildiği gibi CLR'yi #pragma managed
hedeflemek için derlenir. Bu yönerge hakkında daha fazla bilgi için bkz . yönetilen, yönetilmeyen.
DatabaseClass sınıfının özel üyesine dikkat edin: gcroot<DataTable ^> table
. Yerel türler yönetilen türler içeremediğinden gcroot
anahtar sözcüğü gereklidir. hakkında gcroot
daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Bu örnekteki kodun geri kalanı yerel C++ kodudur ve önceki main
yönergesinde #pragma unmanaged
de belirtilmiştir. Bu örnekte, yeni bir DatabaseClass örneği oluşturup tablo oluşturmak ve tablodaki bazı satırları doldurmak için yöntemlerini çağırıyoruz. COM dizelerinin StringCol veritabanı sütunu için değer olarak geçirildiğini unutmayın. DatabaseClass içinde, bu dizeler ad alanında System.Runtime.InteropServices bulunan sıralama işlevselliği kullanılarak yönetilen dizelere sıralanır. Özellikle, yöntemi PtrToStringBSTR için bir BSTR
sıralamak için Stringkullanılır ve yöntemi StringToBSTR bir için sıralamak String için BSTR
kullanılır.
Not
tarafından StringToBSTR ayrılan bellek veya SysFreeString
çağrılarak FreeBSTR serbest bırakılmalıdır.
// adonet_marshal_string_bstr.cpp
// compile with: /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll
#include <comdef.h>
#include <gcroot.h>
#include <iostream>
using namespace std;
#using <System.Data.dll>
using namespace System;
using namespace System::Data;
using namespace System::Runtime::InteropServices;
#define MAXCOLS 100
#pragma managed
class DatabaseClass
{
public:
DatabaseClass() : table(nullptr) { }
void AddRow(BSTR stringColValue)
{
// Add a row to the table.
DataRow ^row = table->NewRow();
row["StringCol"] = Marshal::PtrToStringBSTR(
(IntPtr)stringColValue);
table->Rows->Add(row);
}
void CreateAndPopulateTable()
{
// Create a simple DataTable.
table = gcnew DataTable("SampleTable");
// Add a column of type String to the table.
DataColumn ^column1 = gcnew DataColumn("StringCol",
Type::GetType("System.String"));
table->Columns->Add(column1);
}
int GetValuesForColumn(BSTR dataColumn, BSTR *values,
int valuesLength)
{
// Marshal the name of the column to a managed
// String.
String ^columnStr = Marshal::PtrToStringBSTR(
(IntPtr)dataColumn);
// Get all rows in the table.
array<DataRow ^> ^rows = table->Select();
int len = rows->Length;
len = (len > valuesLength) ? valuesLength : len;
for (int i = 0; i < len; i++)
{
// Marshal each column value from a managed string
// to a BSTR.
values[i] = (BSTR)Marshal::StringToBSTR(
(String ^)rows[i][columnStr]).ToPointer();
}
return len;
}
private:
// Using gcroot, you can use a managed type in
// a native class.
gcroot<DataTable ^> table;
};
#pragma unmanaged
int main()
{
// Create a table and add a few rows to it.
DatabaseClass *db = new DatabaseClass();
db->CreateAndPopulateTable();
BSTR str1 = SysAllocString(L"This is string 1.");
db->AddRow(str1);
BSTR str2 = SysAllocString(L"This is string 2.");
db->AddRow(str2);
// Now retrieve the rows and display their contents.
BSTR values[MAXCOLS];
BSTR str3 = SysAllocString(L"StringCol");
int len = db->GetValuesForColumn(
str3, values, MAXCOLS);
for (int i = 0; i < len; i++)
{
wcout << "StringCol: " << values[i] << endl;
// Deallocate the memory allocated using
// Marshal::StringToBSTR.
SysFreeString(values[i]);
}
SysFreeString(str1);
SysFreeString(str2);
SysFreeString(str3);
delete db;
return 0;
}
StringCol: This is string 1.
StringCol: This is string 2.
Kod Derleniyor
Kodu komut satırından derlemek için kod örneğini adonet_marshal_string_native.cpp adlı bir dosyaya kaydedin ve aşağıdaki deyimi girin:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
ADO.NET için Unicode Dizelerini Hazırlama
Veritabanına yerel Unicode dizesi (wchar_t *
) eklemeyi ve veritabanından yerel Unicode dizesine nasıl sıralamayı System.String gösterir.
Örnek
Bu örnekte DatabaseClass sınıfı bir ADO.NET DataTable nesnesiyle etkileşim kurmak için oluşturulmuştur. Bu sınıfın yerel bir C++ class
olduğunu unutmayın (veya value class
ile karşılaştırıldığındaref class
). Bu sınıfı yerel koddan kullanmak istediğimiz ve yönetilen türleri yerel kodda kullanamayacağınız için bu gereklidir. Bu sınıf, sınıf bildiriminden önceki yönerge tarafından gösterildiği gibi CLR'yi #pragma managed
hedeflemek için derlenir. Bu yönerge hakkında daha fazla bilgi için bkz . yönetilen, yönetilmeyen.
DatabaseClass sınıfının özel üyesine dikkat edin: gcroot<DataTable ^> table
. Yerel türler yönetilen türler içeremediğinden gcroot
anahtar sözcüğü gereklidir. hakkında gcroot
daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Bu örnekteki kodun geri kalanı yerel C++ kodudur ve önceki main
yönergesinde #pragma unmanaged
de belirtilmiştir. Bu örnekte, yeni bir DatabaseClass örneği oluşturup tablo oluşturmak ve tablodaki bazı satırları doldurmak için yöntemlerini çağırıyoruz. Unicode C++ dizelerinin StringCol veritabanı sütunu için değer olarak geçirildiğini unutmayın. DatabaseClass içinde, bu dizeler ad alanında System.Runtime.InteropServices bulunan sıralama işlevselliği kullanılarak yönetilen dizelere sıralanır. Özellikle, yöntemi PtrToStringUni için bir wchar_t *
sıralamak için Stringkullanılır ve yöntemi StringToHGlobalUni bir için sıralamak String için wchar_t *
kullanılır.
Not
tarafından StringToHGlobalUni ayrılan bellek veya GlobalFree
çağrılarak FreeHGlobal serbest bırakılmalıdır.
// adonet_marshal_string_wide.cpp
// compile with: /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll
#include <comdef.h>
#include <gcroot.h>
#include <iostream>
using namespace std;
#using <System.Data.dll>
using namespace System;
using namespace System::Data;
using namespace System::Runtime::InteropServices;
#define MAXCOLS 100
#pragma managed
class DatabaseClass
{
public:
DatabaseClass() : table(nullptr) { }
void AddRow(wchar_t *stringColValue)
{
// Add a row to the table.
DataRow ^row = table->NewRow();
row["StringCol"] = Marshal::PtrToStringUni(
(IntPtr)stringColValue);
table->Rows->Add(row);
}
void CreateAndPopulateTable()
{
// Create a simple DataTable.
table = gcnew DataTable("SampleTable");
// Add a column of type String to the table.
DataColumn ^column1 = gcnew DataColumn("StringCol",
Type::GetType("System.String"));
table->Columns->Add(column1);
}
int GetValuesForColumn(wchar_t *dataColumn, wchar_t **values,
int valuesLength)
{
// Marshal the name of the column to a managed
// String.
String ^columnStr = Marshal::PtrToStringUni(
(IntPtr)dataColumn);
// Get all rows in the table.
array<DataRow ^> ^rows = table->Select();
int len = rows->Length;
len = (len > valuesLength) ? valuesLength : len;
for (int i = 0; i < len; i++)
{
// Marshal each column value from a managed string
// to a wchar_t *.
values[i] = (wchar_t *)Marshal::StringToHGlobalUni(
(String ^)rows[i][columnStr]).ToPointer();
}
return len;
}
private:
// Using gcroot, you can use a managed type in
// a native class.
gcroot<DataTable ^> table;
};
#pragma unmanaged
int main()
{
// Create a table and add a few rows to it.
DatabaseClass *db = new DatabaseClass();
db->CreateAndPopulateTable();
db->AddRow(L"This is string 1.");
db->AddRow(L"This is string 2.");
// Now retrieve the rows and display their contents.
wchar_t *values[MAXCOLS];
int len = db->GetValuesForColumn(
L"StringCol", values, MAXCOLS);
for (int i = 0; i < len; i++)
{
wcout << "StringCol: " << values[i] << endl;
// Deallocate the memory allocated using
// Marshal::StringToHGlobalUni.
GlobalFree(values[i]);
}
delete db;
return 0;
}
StringCol: This is string 1.
StringCol: This is string 2.
Kod Derleniyor
Kodu komut satırından derlemek için kod örneğini adonet_marshal_string_wide.cpp adlı bir dosyaya kaydedin ve aşağıdaki deyimi girin:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_wide.cpp
ADO.NET için VARIANT hazırlama
Veritabanına yerel VARIANT
ekleme ve veritabanından VARIANT
yerel bir öğesine nasıl sıralama System.Object yapılacağını gösterir.
Örnek
Bu örnekte DatabaseClass sınıfı bir ADO.NET DataTable nesnesiyle etkileşim kurmak için oluşturulmuştur. Bu sınıfın yerel bir C++ class
olduğunu unutmayın (veya value class
ile karşılaştırıldığındaref class
). Bu sınıfı yerel koddan kullanmak istediğimiz ve yönetilen türleri yerel kodda kullanamayacağınız için bu gereklidir. Bu sınıf, sınıf bildiriminden önceki yönerge tarafından gösterildiği gibi CLR'yi #pragma managed
hedeflemek için derlenir. Bu yönerge hakkında daha fazla bilgi için bkz . yönetilen, yönetilmeyen.
DatabaseClass sınıfının özel üyesine dikkat edin: gcroot<DataTable ^> table
. Yerel türler yönetilen türler içeremediğinden gcroot
anahtar sözcüğü gereklidir. hakkında gcroot
daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Bu örnekteki kodun geri kalanı yerel C++ kodudur ve önceki main
yönergesinde #pragma unmanaged
de belirtilmiştir. Bu örnekte, yeni bir DatabaseClass örneği oluşturup tablo oluşturmak ve tablodaki bazı satırları doldurmak için yöntemlerini çağırıyoruz. Yerel VARIANT
türlerin ObjectCol veritabanı sütunu için değer olarak geçirildiğini unutmayın. DatabaseClass içinde, bu VARIANT
türler ad alanında bulunan hazırlama işlevselliği kullanılarak yönetilen nesnelere System.Runtime.InteropServices sıralanır. Özellikle, yöntemi GetObjectForNativeVariant için bir VARIANT
sıralamak için Objectkullanılır ve yöntemi GetNativeVariantForObject bir için sıralamak Object için VARIANT
kullanılır.
// adonet_marshal_variant.cpp
// compile with: /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll
#include <comdef.h>
#include <gcroot.h>
#include <iostream>
using namespace std;
#using <System.Data.dll>
using namespace System;
using namespace System::Data;
using namespace System::Runtime::InteropServices;
#define MAXCOLS 100
#pragma managed
class DatabaseClass
{
public:
DatabaseClass() : table(nullptr) { }
void AddRow(VARIANT *objectColValue)
{
// Add a row to the table.
DataRow ^row = table->NewRow();
row["ObjectCol"] = Marshal::GetObjectForNativeVariant(
IntPtr(objectColValue));
table->Rows->Add(row);
}
void CreateAndPopulateTable()
{
// Create a simple DataTable.
table = gcnew DataTable("SampleTable");
// Add a column of type String to the table.
DataColumn ^column1 = gcnew DataColumn("ObjectCol",
Type::GetType("System.Object"));
table->Columns->Add(column1);
}
int GetValuesForColumn(wchar_t *dataColumn, VARIANT *values,
int valuesLength)
{
// Marshal the name of the column to a managed
// String.
String ^columnStr = Marshal::PtrToStringUni(
(IntPtr)dataColumn);
// Get all rows in the table.
array<DataRow ^> ^rows = table->Select();
int len = rows->Length;
len = (len > valuesLength) ? valuesLength : len;
for (int i = 0; i < len; i++)
{
// Marshal each column value from a managed object
// to a VARIANT.
Marshal::GetNativeVariantForObject(
rows[i][columnStr], IntPtr(&values[i]));
}
return len;
}
private:
// Using gcroot, you can use a managed type in
// a native class.
gcroot<DataTable ^> table;
};
#pragma unmanaged
int main()
{
// Create a table and add a few rows to it.
DatabaseClass *db = new DatabaseClass();
db->CreateAndPopulateTable();
BSTR bstr1 = SysAllocString(L"This is a BSTR in a VARIANT.");
VARIANT v1;
v1.vt = VT_BSTR;
v1.bstrVal = bstr1;
db->AddRow(&v1);
int i = 42;
VARIANT v2;
v2.vt = VT_I4;
v2.lVal = i;
db->AddRow(&v2);
// Now retrieve the rows and display their contents.
VARIANT values[MAXCOLS];
int len = db->GetValuesForColumn(
L"ObjectCol", values, MAXCOLS);
for (int i = 0; i < len; i++)
{
switch (values[i].vt)
{
case VT_BSTR:
wcout << L"ObjectCol: " << values[i].bstrVal << endl;
break;
case VT_I4:
cout << "ObjectCol: " << values[i].lVal << endl;
break;
default:
break;
}
}
SysFreeString(bstr1);
delete db;
return 0;
}
ObjectCol: This is a BSTR in a VARIANT.
ObjectCol: 42
Kod Derleniyor
Kodu komut satırından derlemek için kod örneğini adonet_marshal_variant.cpp adlı bir dosyaya kaydedin ve aşağıdaki deyimi girin:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_variant.cpp
ADO.NET için SAFEARRAY hazırlama
Veritabanına yerel SAFEARRAY
bir dizinin nasıl ekleneceğini ve bir veritabanından SAFEARRAY
yerel bir dizinin nasıl sıraleneceğini gösterir.
Örnek
Bu örnekte DatabaseClass sınıfı bir ADO.NET DataTable nesnesiyle etkileşim kurmak için oluşturulmuştur. Bu sınıfın yerel bir C++ class
olduğunu unutmayın (veya value class
ile karşılaştırıldığındaref class
). Bu sınıfı yerel koddan kullanmak istediğimiz ve yönetilen türleri yerel kodda kullanamayacağınız için bu gereklidir. Bu sınıf, sınıf bildiriminden önceki yönerge tarafından gösterildiği gibi CLR'yi #pragma managed
hedeflemek için derlenir. Bu yönerge hakkında daha fazla bilgi için bkz . yönetilen, yönetilmeyen.
DatabaseClass sınıfının özel üyesine dikkat edin: gcroot<DataTable ^> table
. Yerel türler yönetilen türler içeremediğinden gcroot
anahtar sözcüğü gereklidir. hakkında gcroot
daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Bu örnekteki kodun geri kalanı yerel C++ kodudur ve önceki main
yönergesinde #pragma unmanaged
de belirtilmiştir. Bu örnekte, yeni bir DatabaseClass örneği oluşturup tablo oluşturmak ve tablodaki bazı satırları doldurmak için yöntemlerini çağırıyoruz. Yerel SAFEARRAY
türlerin ArrayIntsCol veritabanı sütunu için değer olarak geçirildiğini unutmayın. DatabaseClass içinde, bu SAFEARRAY
türler ad alanında bulunan hazırlama işlevselliği kullanılarak yönetilen nesnelere System.Runtime.InteropServices sıralanır. Özellikle, yöntemi Copy yönetilen bir tamsayı dizisine sıralamak SAFEARRAY
için kullanılır ve yöntemi Copy yönetilen bir tamsayı dizisini olarak SAFEARRAY
sıralamak için kullanılır.
// adonet_marshal_safearray.cpp
// compile with: /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll
#include <comdef.h>
#include <gcroot.h>
#include <iostream>
using namespace std;
#using <System.Data.dll>
using namespace System;
using namespace System::Data;
using namespace System::Runtime::InteropServices;
#define MAXCOLS 100
#pragma managed
class DatabaseClass
{
public:
DatabaseClass() : table(nullptr) { }
void AddRow(SAFEARRAY *arrayIntsColValue)
{
// Add a row to the table.
DataRow ^row = table->NewRow();
int len = arrayIntsColValue->rgsabound[0].cElements;
array<int> ^arr = gcnew array<int>(len);
int *pData;
SafeArrayAccessData(arrayIntsColValue, (void **)&pData);
Marshal::Copy(IntPtr(pData), arr, 0, len);
SafeArrayUnaccessData(arrayIntsColValue);
row["ArrayIntsCol"] = arr;
table->Rows->Add(row);
}
void CreateAndPopulateTable()
{
// Create a simple DataTable.
table = gcnew DataTable("SampleTable");
// Add a column of type String to the table.
DataColumn ^column1 = gcnew DataColumn("ArrayIntsCol",
Type::GetType("System.Int32[]"));
table->Columns->Add(column1);
}
int GetValuesForColumn(wchar_t *dataColumn, SAFEARRAY **values,
int valuesLength)
{
// Marshal the name of the column to a managed
// String.
String ^columnStr = Marshal::PtrToStringUni(
(IntPtr)dataColumn);
// Get all rows in the table.
array<DataRow ^> ^rows = table->Select();
int len = rows->Length;
len = (len > valuesLength) ? valuesLength : len;
for (int i = 0; i < len; i++)
{
// Marshal each column value from a managed array
// of Int32s to a SAFEARRAY of type VT_I4.
values[i] = SafeArrayCreateVector(VT_I4, 0, 10);
int *pData;
SafeArrayAccessData(values[i], (void **)&pData);
Marshal::Copy((array<int> ^)rows[i][columnStr], 0,
IntPtr(pData), 10);
SafeArrayUnaccessData(values[i]);
}
return len;
}
private:
// Using gcroot, you can use a managed type in
// a native class.
gcroot<DataTable ^> table;
};
#pragma unmanaged
int main()
{
// Create a table and add a few rows to it.
DatabaseClass *db = new DatabaseClass();
db->CreateAndPopulateTable();
// Create a standard array.
int originalArray[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Create a SAFEARRAY.
SAFEARRAY *psa;
psa = SafeArrayCreateVector(VT_I4, 0, 10);
// Copy the data from the original array to the SAFEARRAY.
int *pData;
HRESULT hr = SafeArrayAccessData(psa, (void **)&pData);
memcpy(pData, &originalArray, 40);
SafeArrayUnaccessData(psa);
db->AddRow(psa);
// Now retrieve the rows and display their contents.
SAFEARRAY *values[MAXCOLS];
int len = db->GetValuesForColumn(
L"ArrayIntsCol", values, MAXCOLS);
for (int i = 0; i < len; i++)
{
int *pData;
SafeArrayAccessData(values[i], (void **)&pData);
for (int j = 0; j < 10; j++)
{
cout << pData[j] << " ";
}
cout << endl;
SafeArrayUnaccessData(values[i]);
// Deallocate the memory allocated using
// SafeArrayCreateVector.
SafeArrayDestroy(values[i]);
}
SafeArrayDestroy(psa);
delete db;
return 0;
}
0 1 2 3 4 5 6 7 8 9
Kod Derleniyor
Kodu komut satırından derlemek için kod örneğini adonet_marshal_safearray.cpp adlı bir dosyaya kaydedin ve aşağıdaki deyimi girin:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_safearray.cpp
.NET Framework Güvenliği
ADO.NET ile ilgili güvenlik sorunları hakkında bilgi için bkz . ADO.NET Uygulamalarının Güvenliğini Sağlama.
İlgili Bölümler
Bölüm | Açıklama |
---|---|
ADO.NET | .NET programcısının veri erişim hizmetlerini kullanıma sunan bir sınıf kümesi olan ADO.NET genel bakış sağlar. |
Ayrıca bkz.
C++/CLI (Visual C++) ile .NET Programlama
Yerel ve.NET Birlikte Çalışabilirliği