Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Du kan anropa inbyggda funktioner som accepterar strängar i C-stil med hjälp av CLR-strängtypen String när du använder stöd för .NET Framework Platform Invoke (P/Invoke). Vi rekommenderar att du använder C++ Interop-funktionerna i stället för P/Invoke när det är möjligt. P/Invoke ger lite kompileringstidsfelrapportering, är inte typsäker och kan vara omständlig att implementera. Om det ohanterade API:et paketeras som en DLL och källkoden inte är tillgänglig är P/Invoke det enda alternativet. I annat fall kan du läsa Använda C++ Interop (Implicit P/Invoke)).
Exempel
Eftersom interna och hanterade matriser är olika i minnet, kräver överföring av dem över den hanterade/ohanterade gränsen konvertering eller marshaling. Den här artikeln visar hur en matris med enkla objekt (blitable) kan skickas till inbyggda funktioner från hanterad kod.
Precis som när det gäller hanterad/ohanterad datamarshaling i allmänhet används attributet DllImportAttribute för att skapa en hanterad ingångspunkt för varje inbyggd funktion som används. I funktioner som använder matriser som argument MarshalAsAttribute måste attributet användas för att ange hur data ska konverteras. I följande exempel UnmanagedType används uppräkningen för att indikera att den hanterade matrisen har konverterats som en C-matris.
Följande kod består av en ohanterad och en hanterad modul. Den ohanterade modulen är en DLL som definierar en funktion som accepterar en matris med heltal. Den andra modulen är ett hanterat kommandoradsprogram som importerar den här funktionen, men definierar den i termer av en hanterad matris. Det använder MarshalAsAttribute attributet för att ange att matrisen ska konverteras till en intern matris när den anropas.
// TraditionalDll4.cpp
// compile with: /LD /EHsc
#include <iostream>
#define TRADITIONALDLL_EXPORTS
#ifdef TRADITIONALDLL_EXPORTS
#define TRADITIONALDLL_API __declspec(dllexport)
#else
#define TRADITIONALDLL_API __declspec(dllimport)
#endif
extern "C" {
TRADITIONALDLL_API void TakesAnArray(int len, int[]);
}
void TakesAnArray(int len, int a[]) {
printf_s("[unmanaged]\n");
for (int i=0; i<len; i++)
printf("%d = %d\n", i, a[i]);
}
Den hanterade modulen kompileras med hjälp av /clr.
// MarshalBlitArray.cpp
// compile with: /clr
using namespace System;
using namespace System::Runtime::InteropServices;
value struct TraditionalDLL {
[DllImport("TraditionalDLL4.dll")]
static public void TakesAnArray(
int len,[MarshalAs(UnmanagedType::LPArray)]array<int>^);
};
int main() {
array<int>^ b = gcnew array<int>(3);
b[0] = 11;
b[1] = 33;
b[2] = 55;
TraditionalDLL::TakesAnArray(3, b);
Console::WriteLine("[managed]");
for (int i=0; i<3; i++)
Console::WriteLine("{0} = {1}", i, b[i]);
}
Ingen del av DLL:n exponeras för den hanterade koden via det traditionella #include direktivet. Eftersom DLL endast används vid körtid kan problem i funktioner som importeras med hjälp av DllImportAttribute inte identifieras vid kompileringstillfället.