Bagikan melalui


Cara: String COM Marshal Menggunakan Interop C++

Topik ini menunjukkan bagaimana BSTR (format string dasar yang disukai dalam pemrograman COM) dapat diteruskan dari yang dikelola ke fungsi yang tidak dikelola, dan sebaliknya. Untuk mengoperasikan dengan jenis string lain, lihat topik berikut:

Contoh kode berikut menggunakan arahan #pragma terkelola dan tidak dikelola untuk mengimplementasikan fungsi terkelola dan tidak terkelola dalam file yang sama, tetapi fungsi-fungsi ini beroperasi dengan cara yang sama jika ditentukan dalam file terpisah. File yang hanya berisi fungsi yang tidak dikelola tidak perlu dikompilasi dengan /clr (Kompilasi Runtime Bahasa Umum).

Contoh: Meneruskan BSTR dari fungsi terkelola ke tidak terkelola

Contoh berikut menunjukkan bagaimana BSTR (format string yang digunakan dalam pemrograman COM) dapat diteruskan dari yang dikelola ke fungsi yang tidak dikelola. Fungsi terkelola panggilan menggunakan StringToBSTR untuk mendapatkan alamat representasi BSTR dari konten .NET System.String. Pointer ini disematkan menggunakan pin_ptr (C++/CLI) untuk memastikan bahwa alamat fisiknya tidak diubah selama siklus pengumpulan sampah saat fungsi yang tidak dikelola dijalankan. Pengumpul sampah dilarang memindahkan memori sampai pin_ptr (C++/CLI) keluar dari cakupan.

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

Contoh: Meneruskan BSTR dari tidak dikelola ke fungsi terkelola

Contoh berikut menunjukkan bagaimana BSTR dapat diteruskan dari fungsi yang tidak dikelola ke fungsi terkelola. Fungsi terkelola penerima dapat menggunakan string dalam sebagai BSTR atau menggunakan PtrToStringBSTR untuk mengonversinya ke String untuk digunakan dengan fungsi terkelola lainnya. Karena memori yang mewakili BSTR dialokasikan pada tumpukan yang tidak dikelola, tidak ada penyematan yang diperlukan, karena tidak ada pengumpulan sampah pada tumpukan yang tidak dikelola.

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

Baca juga

Menggunakan interop C++ (PInvoke implisit)