De titel is een beetje cryptisch, maar het komt erop neer dat ik probeer in managed C++ (.NET) een plugin te schrijven voor het programma MilkShape3D.
Nu is het zo dat een Milkshape plugin een Win32 DLL moet zijn dat de volgende functie moet implementeren:
waarbij cMsPlugIn (ongeveer) als volgt is gedefinieerd:
Nu, het lijkt me dat de class die cMsPlugin implementeert ook unmanaged moet zijn, omdat een managed class waarschijnlijk niet dezelfde vtable-layout heeft en zijn functies dan dus niet aangeroepen kunnen worden. Maar hoe maak ik dan de overstap van unmanaged naar managed code?
Als ik bijvoorbeeld de Execute()-methode wil implementeren:
Wie kan me de goede richting ophelpen?
Nu is het zo dat een Milkshape plugin een Win32 DLL moet zijn dat de volgende functie moet implementeren:
C++:
1
| cMsPlugIn *CreatePlugIn (); |
waarbij cMsPlugIn (ongeveer) als volgt is gedefinieerd:
C++:
Kortom, cMsPlugIn specificeert een abstract base class (het C++-equivalent van een interface) en CreatePlugIn() moet een implementatie retourneren van deze interface, zodat MilkShape3D de functies van mijn plugin kan aanroepen.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| struct msModel{ int nNumMeshes; int nNumAllocedMeshes; //...en nog meer... }; class cMsPlugIn { public: cMsPlugIn () {}; virtual ~cMsPlugIn () {}; virtual int GetType () = 0; virtual const char * GetTitle () = 0; virtual int Execute (msModel* pModel) = 0; }; |
Nu, het lijkt me dat de class die cMsPlugin implementeert ook unmanaged moet zijn, omdat een managed class waarschijnlijk niet dezelfde vtable-layout heeft en zijn functies dan dus niet aangeroepen kunnen worden. Maar hoe maak ik dan de overstap van unmanaged naar managed code?
Als ik bijvoorbeeld de Execute()-methode wil implementeren:
C++:
Het probleem is dat ik in de declaraties van cMsPlugIn (en dus ook van cMsPlugInImpl) geen managed types mag gebruiken, en ik zie dan ook geen mogelijkheid om het [MarshalAs]-attribuut te gebruiken. Direct casten van een unmanaged naar een managed type kan ook niet, kortom, ik zit een beetje vast.1
2
3
4
5
6
7
8
9
10
11
12
13
| class cMsPluginImpl: cMsPlugIn { //... }; __gc class ManagedModel{ public: int nNumMeshes; int nNumAllocedMeshes; }; int cMsPluginImpl::Execute (msModel* pModel){ //Hoe maak ik van pModel nu een instantie van ManagedModel? } |
Wie kan me de goede richting ophelpen?