Nasıl yapılır: C++ Birlikte Çalışması Kullanarak COM Dizelerini Sıralama

Bu konuda bir BSTR'nin (COM programlamasında tercih edilen temel dizi biçimi) nasıl yönetilen bir işlevden yönetilmeyen bir işleve geçirilebileceği ve tersi gösterilmektedir.Diğer dizgi türleriyle birlikte çalışmak için aşağıdaki konulara bakın:

Aşağıdaki kod örnekleri aynı dosyadaki yönetilen ve yönetilmeyen işlevleri uygulamak için managed, unmanaged #pragma yönergelerini kullanır ancak, bu işlevler ayrı dosyalarda tanımlanırsa aynı şekilde birlikte çalışır.Sadece yönetilmeyen işlevleri içeren dosyalar /clr (Ortak Dil Çalışma Zamanı Derlemesi) ile derlenmek zorunda değildir.

Örnek

Aşağıdaki örnek bir BSTR'nin (COM programlamasında kullanılan bir dizi biçimi) nasıl yönetilen bir işlevden yönetilmeyen bir işleve geçirilebileceğini gösterir.Arama yönetilen işlev, .NET System. String.'in içeriğinin bir BSTR temsili adresini almak için StringToBSTR kullanır.Bu işaretçi, yönetilmeyen işlev çalışırken fiziksel adresinin bir çöp toplama döngüsü sırasında değiştirilmemesini sağlamak için pin_ptr (C++/CLI) kullanarak sabitlenir.Atık toplayıcısının pin_ptr (C++/CLI) kapsam dışına çıkana kadar belleği taşıması yasaklanmıştır.

// 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);
}

Aşağıdaki örnek bir BSTR'nin yönetilmeyen bir işlevden yönetilmeyen bir işleve nasıl geçirilebileceğini gösterir.Yönetilen işlevi alma, dizeyi BSTR olarak kullanabilir veya diğer yönetilen işlevlerle kullanmak için PtrToStringBSTR öğesini String öğesine dönüştürmek için kullanabilir.BSTR'yi temsil eden bellek yönetilmeyen öbekte ayrıldığı için iliştirmeye gerek yoktur, çünkü yönetilmeyen öbekte çöp toplama yoktur.

// 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();
}

Ayrıca bkz.

Başvuru

C++ Birlikte Çalışabilirliği Kullanma (Örtük PInvoke)