Nasıl yapılır: C++ Birlikte Çalışması Kullanarak COM Dizelerini Sıralama
Bu konu başlığında, bir BSTR'nin (COM programlamada tercih edilen temel dize biçimi) yönetilen bir işlevden yönetilmeyen bir işleve nasıl geçirilebileceği ve tam tersi gösterilmektedir. Diğer dize türleriyle birlikte çalışma için aşağıdaki konulara bakın:
Nasıl yapılır: C++ Çalışabilirliği Kullanarak Unicode Dizelerini Sıralama
Nasıl yapılır: C++ Birlikte Çalışması Kullanarak ANSI Dizelerini Sıralama
Aşağıdaki kod örnekleri yönetilen ve yönetilmeyen işlevleri aynı dosyada uygulamak için yönetilen, yönetilmeyen #pragma yönergelerini kullanır, ancak bu işlevler ayrı dosyalarda tanımlanırsa aynı şekilde birlikte çalışır. Yalnızca yönetilmeyen işlevleri içeren dosyaların /clr (Ortak Dil Çalışma Zamanı Derlemesi) ile derlenmesi gerekmez.
Örnek: BSTR'yi yönetilen işlevden yönetilmeyen işleve geçirme
Aşağıdaki örnek, bir BSTR'nin (COM programlamada kullanılan bir dize biçimi) yönetilen bir işlevden yönetilmeyen bir işleve nasıl geçirilebileceğini gösterir. Çağıran yönetilen işlev, bir .NET System.String içeriğinin BSTR gösteriminin adresini almak için kullanır StringToBSTR . Bu işaretçi, yönetilmeyen işlev yürütülürken çöp toplama döngüsü sırasında fiziksel adresinin değiştirilmediğinden emin olmak için pin_ptr (C++/CLI) kullanılarak sabitlenir. pin_ptr (C++/CLI) kapsam dışına çıkana kadar çöp toplayıcının belleği taşıması yasaktı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);
}
Örnek: BSTR'yi yönetilmeyen işlevden yönetilen işleve geçirme
Aşağıdaki örnek, bir BSTR'nin yönetilmeyen bir işlevden yönetilen bir işleve nasıl geçirilebileceğini gösterir. Alan yönetilen işlev, dizesini BSTR olarak kullanabilir veya PtrToStringBSTR diğer yönetilen işlevlerle kullanmak üzere ' String a dönüştürmek için kullanabilir. BSTR'yi temsil eden bellek yönetilmeyen yığında ayrıldığından, yönetilmeyen yığında çöp toplama olmadığından sabitleme gerekmez.
// 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();
}