Практическое руководство. Маршалирование строк модели COM с использованием взаимодействия C++

В этом разделе описывается порядок передачи строк BSTR (основной формат строк в программировании с использованием модели COM) между управляемыми и неуправляемыми функциями.Дополнительные сведения о взаимодействии с другими строковыми типами см. в следующих разделах:

В следующем примере кода используются директивы #pragma managed, unmanaged, которые встраивают управляемые и неуправляемые функции в один файл. Эти функции также взаимодействуют и в случае их распределения в отдельные файлы.Файлы, содержащие только неуправляемые функции, не требуется компилировать с использованием параметра /clr (компиляция CLR).

Пример

В следующем примере описывается порядок передачи строк BSTR (формат строк в программировании с использованием модели COM) из управляемой в неуправляемую функцию.В вызывающей управляемой функции используется метод StringToBSTR для получения адреса представления содержимого строки .NET System.String в формате BSTR.Этот указатель закрепляется с помощью функции pin_ptr (C++/CLI). Благодаря этому физический адрес указателя не изменяется в процессе сборки мусора при выполнении неуправляемой функции.Сборщик мусора не освобождает память до тех пор, пока закрепленный с помощью функции pin_ptr (C++/CLI) указатель не выйдет за пределы области действия.

// MarshalBSTR1.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(BSTR bstr) {
   printf_s("%S", bstr);
}

#pragma managed

int main() {
   String^ s = "test string";

   IntPtr ip = Marshal::StringToBSTR(s);
   BSTR bs = static_cast<BSTR>(ip.ToPointer());
   pin_ptr<BSTR> b = &bs;

   NativeTakesAString( bs );
   Marshal::FreeBSTR(ip);
}

В следующем примере описывается порядок передачи строк BSTR из неуправляемой в неуправляемую функцию.При получении управляемая функция может использовать строку BSTR или использовать в качестве PtrToStringBSTR для преобразования его в String для использования с другими управляемыми функциями.Поскольку память, представляющая строку BSTR, выделяется в неуправляемой куче, в которой не выполняется сборка мусора, закрепление не требуется.

// MarshalBSTR2.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedTakesAString(BSTR bstr) {
   String^ s = Marshal::PtrToStringBSTR(static_cast<IntPtr>(bstr));
   Console::WriteLine("(managed) convered BSTR to String: '{0}'", s);
}

#pragma unmanaged

void UnManagedFunc() {
   BSTR bs = SysAllocString(L"test string");
   printf_s("(unmanaged) passing BSTR to managed func...\n");
   ManagedTakesAString(bs);
}

#pragma managed

int main() {
   UnManagedFunc();
}

См. также

Ссылки

Использование взаимодействия языка C++ (неявный PInvoke)