Aracılığıyla paylaş


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:

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

Ayrıca bkz.

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