Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A felügyelt meghatalmazottak függvénymutatók helyett használhatók, ha nem felügyelt függvényekkel működnek együtt a .NET-keretrendszer P/Invoke funkcióival. Javasoljuk azonban, hogy ha lehetséges, használja inkább a C++ Interop funkciókat. A P/Invoke kevés fordítási idejű hibajelentést biztosít, nem típusbiztos, és időigényes lehet implementálni. Ha a nem felügyelt API DLL-ként van csomagolva, és a forráskód nem érhető el, a P/Invoke az egyetlen lehetőség. Egyéb esetben lásd az alábbi cikkeket:
A függvénymutatókat argumentumként használó nem felügyelt API-k meghívhatók felügyelt kódból a natív függvénymutató helyett egy felügyelt meghatalmazott használatával. A fordító automatikusan átalakítja a delegáltakat nem felügyelt függvényekhez, mint függvénymutatókat. Beszúrja a szükséges felügyelt/nem felügyelt átmeneti kódot.
példa
A következő kód egy nem felügyelt és egy felügyelt modulból áll. A nem felügyelt modul egy DLL, amely egy függvénymutatót elfogadó függvényt TakesCallback definiál. Ez a cím a függvény végrehajtására szolgál.
// TraditionalDll5.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" {
/* Declare an unmanaged function type that takes two int arguments
Note the use of __stdcall for compatibility with managed code */
typedef int (__stdcall *CALLBACK)(int);
TRADITIONALDLL_API int TakesCallback(CALLBACK fp, int);
}
int TakesCallback(CALLBACK fp, int n) {
printf_s("[unmanaged] got callback address, calling it...\n");
return fp(n);
}
A felügyelt modul egy olyan delegáltat definiál, amit a natív kód számára függvénymutatóként adnak át. Az attribútum használatával DllImportAttribute teszi hozzáférhetővé a natív TakesCallback függvényt a felügyelt kód számára. A main függvényben egy példánya jön létre a meghatalmazottnak, és átadásra kerül a TakesCallback függvénynek. A program kimenete azt mutatja be, hogy ezt a függvényt a natív TakesCallback függvény hajtja végre.
A felügyelt függvény letiltja a felügyelt delegált szemétgyűjtését, hogy a .NET-keretrendszer szemétgyűjtése ne helyezze át a delegáltat a natív függvény végrehajtása közben.
// MarshalDelegate.cpp
// compile with: /clr
using namespace System;
using namespace System::Runtime::InteropServices;
public delegate int GetTheAnswerDelegate(int);
public value struct TraditionalDLL {
[DllImport("TraditionalDLL5.dll")]
static public int TakesCallback(GetTheAnswerDelegate^ pfn, int n);
};
int GetNumber(int n) {
Console::WriteLine("[managed] callback!");
static int x = 0;
++x;
return x + n;
}
int main() {
GetTheAnswerDelegate^ fp = gcnew GetTheAnswerDelegate(GetNumber);
pin_ptr<GetTheAnswerDelegate^> pp = &fp;
Console::WriteLine("[managed] sending delegate as callback...");
int answer = TraditionalDLL::TakesCallback(fp, 42);
}
A DLL egyetlen része sem érhető el a feldolgozott kód számára a hagyományos #include direktíva használatával. Valójában a DLL csak futtatókörnyezetben érhető el, így a használatával DllImportAttribute importált függvényekkel kapcsolatos problémák fordításkor nem észlelhetők.
Lásd még
Explicit P/Invoke használata c++ (DllImport attribútum) nyelven