Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
ADO.NET adalah API dari .NET Framework untuk mengakses data dan menyediakan kekuatan serta kemudahan penggunaan yang tanpa banding dibandingkan solusi akses data sebelumnya. Bagian ini menjelaskan beberapa masalah yang melibatkan ADO.NET, yang khusus untuk pengguna Visual C++, seperti pengaturan tipe asli.
ADO.NET berjalan di bawah Common Language Runtime (CLR). Oleh karena itu, aplikasi apa pun yang berinteraksi dengan ADO.NET juga harus menargetkan CLR. Namun, itu tidak berarti bahwa aplikasi asli tidak dapat menggunakan ADO.NET. Contoh-contoh ini akan menunjukkan cara berinteraksi dengan database ADO.NET dari kode asli.
Pengelolaan String ANSI untuk ADO.NET
Menunjukkan cara menambahkan string asli (char *) ke database dan cara mengonversi System.String dari database ke string asli.
Contoh
Dalam contoh ini, kelas DatabaseClass dibuat untuk berinteraksi dengan objek ADO.NET DataTable . Perhatikan bahwa kelas ini adalah C++ class asli (dibandingkan dengan ref class atau value class). Ini diperlukan karena kami ingin menggunakan kelas ini dari kode asli, dan Anda tidak dapat menggunakan jenis terkelola dalam kode asli. Kelas ini akan dikompilasi untuk menargetkan CLR, seperti yang ditunjukkan oleh #pragma managed arahan sebelum deklarasi kelas. Untuk informasi selengkapnya tentang arahan ini, lihat terkelola, tidak dikelola.
Perhatikan anggota privat kelas DatabaseClass: gcroot<DataTable ^> table. Karena tipe asli tidak dapat mengandung tipe terkelola, kata kunci gcroot diperlukan. Untuk informasi selengkapnya tentang gcroot, lihat Cara: Mendeklarasikan Handle dalam Jenis asli.
Sisa kode dalam contoh ini adalah kode C++ asli, seperti yang ditunjukkan oleh direktif #pragma unmanaged sebelumnya main. Dalam contoh ini, kita membuat instans baru DatabaseClass dan memanggil metodenya untuk membuat tabel dan mengisi beberapa baris dalam tabel. Perhatikan bahwa string C++ asli sedang diteruskan sebagai nilai untuk kolom database StringCol. Di dalam DatabaseClass, string ini dikonversi ke string terkelola menggunakan fungsi marshaling yang ditemukan di namespace System.Runtime.InteropServices. Secara khusus, metode PtrToStringAnsi ini digunakan untuk marshal a char * ke String, dan metode StringToHGlobalAnsi ini digunakan untuk marshal a String ke char *.
Catatan
Memori yang dialokasikan oleh StringToHGlobalAnsi harus dibebaskan dengan memanggil baik FreeHGlobal atau GlobalFree.
// 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.
Mengompilasi Kode
Untuk mengkompilasi kode dari baris perintah, simpan contoh kode dalam file bernama adonet_marshal_string_native.cpp dan masukkan pernyataan berikut:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
Pengelolaan String BSTR untuk ADO.NET
Menunjukkan cara menambahkan string COM (BSTR) ke database dan cara melakukan marshal System.String dari database ke BSTR.
Contoh
Dalam contoh ini, kelas DatabaseClass dibuat untuk berinteraksi dengan objek ADO.NET DataTable . Perhatikan bahwa kelas ini adalah C++ class asli (dibandingkan dengan ref class atau value class). Ini diperlukan karena kami ingin menggunakan kelas ini dari kode asli, dan Anda tidak dapat menggunakan jenis terkelola dalam kode asli. Kelas ini akan dikompilasi untuk menargetkan CLR, seperti yang ditunjukkan oleh #pragma managed arahan sebelum deklarasi kelas. Untuk informasi selengkapnya tentang arahan ini, lihat terkelola, tidak dikelola.
Perhatikan anggota privat kelas DatabaseClass: gcroot<DataTable ^> table. Karena tipe asli tidak dapat mengandung tipe terkelola, kata kunci gcroot diperlukan. Untuk informasi selengkapnya tentang gcroot, lihat Cara: Mendeklarasikan Handle dalam Jenis asli.
Sisa kode dalam contoh ini adalah kode C++ asli, seperti yang ditunjukkan oleh direktif #pragma unmanaged sebelumnya main. Dalam contoh ini, kita membuat instans baru DatabaseClass dan memanggil metodenya untuk membuat tabel dan mengisi beberapa baris dalam tabel. Perhatikan bahwa string COM sedang diteruskan sebagai nilai untuk kolom database StringCol. Di dalam DatabaseClass, string ini dikonversi ke string terkelola menggunakan fungsi marshaling yang ditemukan di namespace System.Runtime.InteropServices. Secara khusus, metode PtrToStringBSTR ini digunakan untuk marshal a BSTR ke String, dan metode StringToBSTR ini digunakan untuk marshal a String ke BSTR.
Catatan
Memori yang dialokasikan oleh StringToBSTR harus dibebaskan dengan memanggil baik FreeBSTR atau SysFreeString.
// 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.
Mengompilasi Kode
Untuk mengkompilasi kode dari baris perintah, simpan contoh kode dalam file bernama adonet_marshal_string_native.cpp dan masukkan pernyataan berikut:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
Pengelolaan String Unicode untuk ADO.NET
Menunjukkan cara menambahkan string Unicode asli (wchar_t *) ke dalam database dan cara mentransfer data System.String dari database ke string Unicode asli.
Contoh
Dalam contoh ini, kelas DatabaseClass dibuat untuk berinteraksi dengan objek ADO.NET DataTable . Perhatikan bahwa kelas ini adalah C++ class asli (dibandingkan dengan ref class atau value class). Ini diperlukan karena kami ingin menggunakan kelas ini dari kode asli, dan Anda tidak dapat menggunakan jenis terkelola dalam kode asli. Kelas ini akan dikompilasi untuk menargetkan CLR, seperti yang ditunjukkan oleh #pragma managed arahan sebelum deklarasi kelas. Untuk informasi selengkapnya tentang arahan ini, lihat terkelola, tidak dikelola.
Perhatikan anggota privat kelas DatabaseClass: gcroot<DataTable ^> table. Karena jenis asli tidak dapat berisi jenis terkelola, kata kunci gcroot diperlukan. Untuk informasi selengkapnya tentang gcroot, lihat Cara: Mendeklarasikan Handle dalam Tipe Native.
Sisa kode dalam contoh ini adalah kode C++ asli, seperti yang ditunjukkan oleh direktif #pragma unmanaged sebelumnya main. Dalam contoh ini, kita membuat instans baru DatabaseClass dan memanggil metodenya untuk membuat tabel dan mengisi beberapa baris dalam tabel. Perhatikan bahwa string Unicode C++ sedang diteruskan sebagai nilai untuk kolom database StringCol. Di dalam DatabaseClass, string ini dikonversi ke string terkelola menggunakan fungsi marshaling yang ditemukan di namespace System.Runtime.InteropServices. Secara khusus, metode PtrToStringUni ini digunakan untuk marshal a wchar_t * ke String, dan metode StringToHGlobalUni ini digunakan untuk marshal a String ke wchar_t *.
Catatan
Memori yang dialokasikan oleh StringToHGlobalUni harus dibebaskan dengan memanggil baik FreeHGlobal atau GlobalFree.
// 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.
Mengompilasi Kode
Untuk mengkompilasi kode dari baris perintah, simpan contoh kode dalam file bernama adonet_marshal_string_wide.cpp dan masukkan pernyataan berikut:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_wide.cpp
Memproses VARIANT untuk ADO.NET
Menunjukkan cara menambahkan VARIANT bawaan ke database dan cara mengonversi System.Object dari database ke VARIANT bawaan.
Contoh
Dalam contoh ini, kelas DatabaseClass dibuat untuk berinteraksi dengan objek ADO.NET DataTable . Perhatikan bahwa kelas ini adalah C++ class asli (dibandingkan dengan ref class atau value class). Ini diperlukan karena kami ingin menggunakan kelas ini dari kode asli, dan Anda tidak dapat menggunakan jenis terkelola dalam kode asli. Kelas ini akan dikompilasi untuk menargetkan CLR, seperti yang ditunjukkan oleh #pragma managed direktif sebelum deklarasi kelas. Untuk informasi selengkapnya tentang arahan ini, lihat terkelola, tidak dikelola.
Perhatikan anggota privat kelas DatabaseClass: gcroot<DataTable ^> table. Karena jenis asli tidak dapat berisi jenis terkelola, kata kunci gcroot diperlukan. Untuk informasi selengkapnya tentang gcroot, lihat Cara: Mendeklarasikan Handle dalam Tipe Native.
Sisa kode dalam contoh ini adalah kode C++ asli, seperti yang ditunjukkan oleh direktif #pragma unmanaged sebelumnya main. Dalam contoh ini, kita membuat instans baru DatabaseClass dan memanggil metodenya untuk membuat tabel dan mengisi beberapa baris dalam tabel. Perhatikan bahwa jenis asli VARIANT sedang diteruskan sebagai nilai untuk kolom database ObjectCol. Di dalam DatabaseClass, jenis ini VARIANT diarahkan ke objek terkelola menggunakan fungsionalitas marshaling yang ditemukan di namespace System.Runtime.InteropServices. Secara khusus, metode GetObjectForNativeVariant digunakan untuk mengarahkan VARIANT ke Object, dan metode GetNativeVariantForObject digunakan untuk mengarahkan Object ke VARIANT.
// 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
Mengompilasi Kode
Untuk mengkompilasi kode dari baris perintah, simpan contoh kode dalam file bernama adonet_marshal_variant.cpp dan masukkan pernyataan berikut:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_variant.cpp
Mengatur SAFEARRAY untuk ADO.NET
Menunjukkan cara menambahkan komponen native SAFEARRAY ke database dan cara memindahkan array terkelola dari database ke komponen native SAFEARRAY.
Contoh
Dalam contoh ini, kelas DatabaseClass dibuat untuk berinteraksi dengan objek ADO.NET DataTable . Perhatikan bahwa kelas ini adalah C++ class asli (dibandingkan dengan ref class atau value class). Ini diperlukan karena kami ingin menggunakan kelas ini dari kode asli, dan Anda tidak dapat menggunakan jenis terkelola dalam kode asli. Kelas ini akan dikompilasi untuk menargetkan CLR, seperti yang ditunjukkan oleh #pragma managed arahan sebelum deklarasi kelas. Untuk informasi selengkapnya tentang arahan ini, lihat terkelola, tidak dikelola.
Perhatikan anggota privat kelas DatabaseClass: gcroot<DataTable ^> table. Karena tipe asli tidak dapat mengandung tipe terkelola, kata kunci gcroot diperlukan. Untuk informasi selengkapnya tentang gcroot, lihat Cara: Mendeklarasikan Handle dalam Jenis asli.
Sisa kode dalam contoh ini adalah kode C++ asli, seperti yang ditunjukkan oleh direktif #pragma unmanaged sebelumnya main. Dalam contoh ini, kita membuat instans baru DatabaseClass dan memanggil metodenya untuk membuat tabel dan mengisi beberapa baris dalam tabel. Perhatikan bahwa jenis asli SAFEARRAY sedang diteruskan sebagai nilai untuk kolom database ArrayIntsCol. Di dalam DatabaseClass, jenis ini SAFEARRAY diarahkan ke objek terkelola menggunakan fungsionalitas marshaling yang ditemukan di namespace System.Runtime.InteropServices. Secara khusus, metode Copy digunakan untuk melakukan pengubahan SAFEARRAY menjadi array bilangan bulat yang terkelola, dan metode Copy digunakan untuk mengubah array bilangan bulat yang terkelola menjadi SAFEARRAY.
// 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
Mengompilasi Kode
Untuk mengkompilasi kode dari baris perintah, simpan contoh kode dalam file bernama adonet_marshal_safearray.cpp dan masukkan pernyataan berikut:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_safearray.cpp
Keamanan .NET Framework
Untuk informasi tentang masalah keamanan yang melibatkan ADO.NET, lihat Mengamankan Aplikasi ADO.NET.
Bagian Terkait
| Bagian | Deskripsi |
|---|---|
| ADO.NET | Memberikan gambaran umum tentang ADO.NET, sekumpulan kelas yang mengekspos layanan akses data ke programmer .NET. |
Lihat juga
Pemrograman .NET dengan C++/CLI (Visual C++)
Interoperabilitas Native dan .NET