Compartilhar via


Como: realizar realizar marshaling BSTR strings para o ADO.NET

Demonstra como adicionar uma seqüência de caracteres COM (BSTR) a um banco de dados e como realizar realizar marshaling um System.String de um banco de dados para um BSTR.

Exemplo

Neste exemplo, a classe DatabaseClass é criada para interagir com um ADO.NET DataTable objeto. Observe que este clsistema autônomos é um C++ nativo class (sistema autônomo em comparação com um ref class ou value class). Isso é necessário porque queremos usar essa classe de código nativo e não é possível usar tipos gerenciado em código nativo.Este clsistema autônomos será ser compilado para direcionar o CLR sistema autônomo é indicado pelo #pragma managed diretiva antecedendo a declaração clsistema autônomos. Para obter mais informações sobre essa diretiva, consulte gerenciado, não gerenciado.

Observe o membro particular da classe DatabaseClass: gcroot<DataTable ^> table.Como tipos nativo não podem conter tipos gerenciado, a gcroot palavra-chave é necessária. Para obter mais informações sobre gcroot, consulte: Como: Declarar Handles em tipos nativo.

O restante do código no exemplo é o código C++ nativo, conforme indicado pelo #pragma unmanaged diretiva anterior main. Neste exemplo, estamos criando uma nova instância de DatabaseClass e chamando seus métodos para criar uma tabela e popular algumas linhas da tabela.Observe que estão sendo passadas COM seqüências de caracteres sistema autônomo valores da coluna do banco de dados StringCol.Dentro de DatabaseClass, essas cadeias de caracteres são empacotadas para seqüências de caracteres gerenciadas usando a funcionalidade de marshaling encontrada no System.Runtime.InteropServices espaço para nome. Especificamente, o método PtrToStringBSTR usado para realizar realizar marshaling uma BSTR para um Stringe o método StringToBSTR usado para realizar realizar marshaling uma String para um BSTR.

Observação:

A memória alocada por StringToBSTR deve ser desalocada chamando qualquer um FreeBSTR ou 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.

Compilando o código

  • Para compilar o código a partir da linha de comando, salvar o exemplo de código em um arquivo chamado adonet_marshal_string_native.cpp e insira a demonstrativo a seguir:

    cl /clr /FU System.dll /FU System.Data.dll /FU System.Xml.dll adonet_marshal_string_native.cpp
    

Segurança

Para obter informações sobre questões de segurança envolvendo o ADO.NET, consulte Protegendo aplicativos do ADO.NET.

Consulte também

Referência

System.Runtime.InteropServices

Outros recursos

Acesso de dados usando ADO.NET em C++

ADO.NET

Interoperabilidade

Nativo e interoperabilidade .NET