Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
ADO.NET är .NET Framework-API:et för dataåtkomst och ger energi och användarvänlighet som inte matchas av tidigare dataåtkomstlösningar. I det här avsnittet beskrivs några av de problem som rör ADO.NET som är unika för Visual C++-användare, till exempel att konvertera interna typer.
ADO.NET körs under COMMON Language Runtime (CLR). Därför måste alla program som interagerar med ADO.NET även rikta in sig på CLR. Det innebär dock inte att interna program inte kan använda ADO.NET. De här exemplen visar hur du interagerar med en ADO.NET databas från inbyggd kod.
Hantering av ANSI-strängar för ADO.NET
Visar hur du lägger till en intern sträng (char *
) i en databas och hur du konverterar en System.String från en databas till en intern sträng.
Exempel
I det här exemplet skapas klassen DatabaseClass för att interagera med ett ADO.NET DataTable objekt. Observera att den här klassen är en intern C++ class
(jämfört med en ref class
eller value class
). Detta är nödvändigt eftersom vi vill använda den här klassen från inbyggd kod och du inte kan använda hanterade typer i inbyggd kod. Den här klassen kompileras för att rikta in sig på CLR, vilket anges i #pragma managed
direktivet före klassdeklarationen. Mer information om det här direktivet finns i Hanterad, ohanterad.
Observera den privata medlemmen i klassen DatabaseClass: gcroot<DataTable ^> table
. Eftersom interna typer inte kan innehålla hanterade typer är nyckelordet gcroot
nödvändigt. Mer information om gcroot
finns i How to: Declare Handles in Native Types (Deklarera handtag i inbyggda typer).
Resten av koden i det här exemplet är inbyggd C++-kod, vilket anges i #pragma unmanaged
direktivet före main
. I det här exemplet skapar vi en ny instans av DatabaseClass och anropar dess metoder för att skapa en tabell och fylla i några rader i tabellen. Observera att interna C++-strängar skickas som värden för databaskolumnen StringCol. I DatabaseClass konverteras dessa strängar till hanterade strängar med hjälp av de marshaling-funktioner som finns i System.Runtime.InteropServices namnområdet. Mer specifikt används metoden PtrToStringAnsi för att konvertera en char *
till en String, och metoden StringToHGlobalAnsi används för att konvertera en String till en char *
.
Anmärkning
Det minne som allokeras av StringToHGlobalAnsi måste frigöras genom att anropa antingen FreeHGlobal eller 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.
Kompilera koden
Om du vill kompilera koden från kommandoraden sparar du kodexemplet i en fil med namnet adonet_marshal_string_native.cpp och anger följande instruktion:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
Hantera BSTR-strängar för ADO.NET
Visar hur du lägger till en COM-sträng (BSTR
) i en databas och hur du konverterar en System.String från en databas till en BSTR
.
Exempel
I det här exemplet skapas klassen DatabaseClass för att interagera med ett ADO.NET DataTable objekt. Observera att den här klassen är en intern C++ class
(jämfört med en ref class
eller value class
). Detta är nödvändigt eftersom vi vill använda den här klassen från inbyggd kod och du inte kan använda hanterade typer i inbyggd kod. Den här klassen kompileras för att rikta in sig på CLR, vilket anges i #pragma managed
direktivet före klassdeklarationen. Mer information om det här direktivet finns i Hanterad, ohanterad.
Observera den privata medlemmen i klassen DatabaseClass: gcroot<DataTable ^> table
. Eftersom interna typer inte kan innehålla hanterade typer är nyckelordet gcroot
nödvändigt. Mer information om gcroot
finns i How to: Declare Handles in Native Types (Deklarera handtag i inbyggda typer).
Resten av koden i det här exemplet är inbyggd C++-kod, vilket anges i #pragma unmanaged
direktivet före main
. I det här exemplet skapar vi en ny instans av DatabaseClass och anropar dess metoder för att skapa en tabell och fylla i några rader i tabellen. Observera att COM-strängar skickas som värden för databaskolumnen StringCol. I DatabaseClass konverteras dessa strängar till hanterade strängar med hjälp av de marshaling-funktioner som finns i System.Runtime.InteropServices namnområdet. Mer specifikt används metoden PtrToStringBSTR för att konvertera en BSTR
till en String, och metoden StringToBSTR används för att konvertera en String till en BSTR
.
Anmärkning
Det minne som allokeras av StringToBSTR måste frigöras genom att anropa antingen FreeBSTR eller 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.
Kompilera koden
Om du vill kompilera koden från kommandoraden sparar du kodexemplet i en fil med namnet adonet_marshal_string_native.cpp och anger följande instruktion:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
Marshal Unicode-strängar för ADO.NET
Visar hur du lägger till en intern Unicode-sträng (wchar_t *
) i en databas och hur du konverterar en System.String från en databas till en intern Unicode-sträng.
Exempel
I det här exemplet skapas klassen DatabaseClass för att interagera med ett ADO.NET DataTable objekt. Observera att den här klassen är en intern C++ class
(jämfört med en ref class
eller value class
). Detta är nödvändigt eftersom vi vill använda den här klassen från inbyggd kod och du inte kan använda hanterade typer i inbyggd kod. Den här klassen kompileras för att rikta in sig på CLR, vilket anges i #pragma managed
direktivet före klassdeklarationen. Mer information om det här direktivet finns i Hanterad, ohanterad.
Observera den privata medlemmen i klassen DatabaseClass: gcroot<DataTable ^> table
. Eftersom interna typer inte kan innehålla hanterade typer är nyckelordet gcroot
nödvändigt. Mer information om gcroot
finns i How to: Declare Handles in Native Types (Deklarera handtag i inbyggda typer).
Resten av koden i det här exemplet är inbyggd C++-kod, vilket anges i #pragma unmanaged
direktivet före main
. I det här exemplet skapar vi en ny instans av DatabaseClass och anropar dess metoder för att skapa en tabell och fylla i några rader i tabellen. Observera att Unicode C++-strängar skickas som värden för databaskolumnen StringCol. I DatabaseClass konverteras dessa strängar till hanterade strängar med hjälp av de marshaling-funktioner som finns i System.Runtime.InteropServices namnområdet. Mer specifikt används metoden PtrToStringUni för att konvertera en wchar_t *
till en String, och metoden StringToHGlobalUni används för att konvertera en String till en wchar_t *
.
Anmärkning
Det minne som allokeras av StringToHGlobalUni måste frigöras genom att anropa antingen FreeHGlobal eller 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.
Kompilera koden
Om du vill kompilera koden från kommandoraden sparar du kodexemplet i en fil med namnet adonet_marshal_string_wide.cpp och anger följande instruktion:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_wide.cpp
Samordna en VARIANT för ADO.NET
Visar hur du lägger till en intern VARIANT
i en databas och hur du konverterar en System.Object från en databas till en intern VARIANT
.
Exempel
I det här exemplet skapas klassen DatabaseClass för att interagera med ett ADO.NET DataTable objekt. Observera att den här klassen är en intern C++ class
(jämfört med en ref class
eller value class
). Detta är nödvändigt eftersom vi vill använda den här klassen från inbyggd kod och du inte kan använda hanterade typer i inbyggd kod. Den här klassen kompileras för att rikta in sig på CLR, vilket anges i #pragma managed
direktivet före klassdeklarationen. Mer information om det här direktivet finns i Hanterad, ohanterad.
Observera den privata medlemmen i klassen DatabaseClass: gcroot<DataTable ^> table
. Eftersom interna typer inte kan innehålla hanterade typer är nyckelordet gcroot
nödvändigt. Mer information om gcroot
finns i How to: Declare Handles in Native Types (Deklarera handtag i inbyggda typer).
Resten av koden i det här exemplet är inbyggd C++-kod, vilket anges i #pragma unmanaged
direktivet före main
. I det här exemplet skapar vi en ny instans av DatabaseClass och anropar dess metoder för att skapa en tabell och fylla i några rader i tabellen. Observera att interna VARIANT
typer skickas som värden för databaskolumnen ObjectCol. I DatabaseClass konverteras dessa VARIANT
typer till hanterade objekt med hjälp av de marshaling-funktioner som finns i System.Runtime.InteropServices namnområdet. Mer specifikt används metoden GetObjectForNativeVariant för att konvertera en VARIANT
till en Object, och metoden GetNativeVariantForObject används för att konvertera en Object till en 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
Kompilera koden
Om du vill kompilera koden från kommandoraden sparar du kodexemplet i en fil med namnet adonet_marshal_variant.cpp och anger följande instruktion:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_variant.cpp
Ordna en SAFEARRAY för ADO.NET
Visar hur du lägger till en intern SAFEARRAY
till en databas och hur du konverterar en hanterad matris från en databas till en intern SAFEARRAY
.
Exempel
I det här exemplet skapas klassen DatabaseClass för att interagera med ett ADO.NET DataTable objekt. Observera att den här klassen är en intern C++ class
(jämfört med en ref class
eller value class
). Detta är nödvändigt eftersom vi vill använda den här klassen från inbyggd kod och du inte kan använda hanterade typer i inbyggd kod. Den här klassen kompileras för att rikta in sig på CLR, vilket anges i #pragma managed
direktivet före klassdeklarationen. Mer information om det här direktivet finns i Hanterad, ohanterad.
Observera den privata medlemmen i klassen DatabaseClass: gcroot<DataTable ^> table
. Eftersom interna typer inte kan innehålla hanterade typer är nyckelordet gcroot
nödvändigt. Mer information om gcroot
finns i How to: Declare Handles in Native Types (Deklarera handtag i inbyggda typer).
Resten av koden i det här exemplet är inbyggd C++-kod, vilket anges i #pragma unmanaged
direktivet före main
. I det här exemplet skapar vi en ny instans av DatabaseClass och anropar dess metoder för att skapa en tabell och fylla i några rader i tabellen. Observera att interna SAFEARRAY
typer skickas som värden för databaskolumnen ArrayIntsCol. I DatabaseClass konverteras dessa SAFEARRAY
typer till hanterade objekt med hjälp av de marshaling-funktioner som finns i System.Runtime.InteropServices namnområdet. Mer specifikt används metoden Copy för att konvertera en SAFEARRAY
till en hanterad matris med heltal och metoden Copy används för att konvertera en hanterad matris med heltal till en 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
Kompilera koden
Om du vill kompilera koden från kommandoraden sparar du kodexemplet i en fil med namnet adonet_marshal_safearray.cpp och anger följande instruktion:
cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_safearray.cpp
.NET Framework-säkerhet
Information om säkerhetsproblem som rör ADO.NET finns i Skydda ADO.NET-program.
Relaterade avsnitt
Sektion | Beskrivning |
---|---|
ADO.NET | Ger en översikt över ADO.NET, en uppsättning klasser som exponerar dataåtkomsttjänster för .NET-programmeraren. |
Se även
.NET-programmering med C++/CLI (Visual C++)
Native och .NET-interoperabilitet