クラスをLPVOIDにキャストし、それをインターフェイスクラスに再キャストするときに問題があります。ここでは単純化されたコードは次のとおりです。インターフェイス参照の無効なキャスト例外
public interface class IEventRaiser
{
void fireAppDisconnect()
// some other methods
}
interface class ISpecificEventRaiser : IEventRaiser
{
// some specific methods
}
public ref class ManagedItem
{
ManagedItem()
{
eventRaiser = gcnew EventRaiser();
LPVOID lP = reinterpret_cast<LPVOID>(GCHandle::ToIntPtr(GCHandle::Alloc(eventRaiser)).ToPointer();
item = new UnmanagedItem(lP);
}
// some implementation
ref class EventRaiser : public ISpecificEventRaiser
{
virtual void fireAppDisconnect();
// other methods
};
EventRaiser^ eventRaiser;
UnmanagedItem* item;
};
public class UnmanagedItem
{
UnmanagedItem(LPVOID eventRaiser)
{
IEventRaiser^ r;
IntPtr pointer(eventRaiser);
handle = GCHandle::FromIntPtr(pointer);
r = safe_cast<IEventRaiser^>(handle.Target); // InvalidCastException : Unable to cast object of type 'EventRaiser' to type 'IEventRaiser'.
}
};
私は前にそれを試してみましたので、IEventRaiser ^へ^ EventRaiserにキャストすることには問題があってはなりません。会話をLPVOIDしようとする前に、うまくいきました。しかし、私はそれをLPVOIDにキャストし、それをIEventRaiserに再キャストすると、InvalidCastExceptionがスローされます。 LPVOIDでキャスティングを正しく行うにはどうすればいいですか?
親愛なる@HansPassant、 それはアプリのライフタイムまで生き残り、私はデストラクタでhandle.free()を呼び出します。 IEventRaiserとして参照をラップしようとしましたが、同じ例外がスローされます。次のように。 ISpecificEventRaiser^sEventRaiser =(ISpecificEventRaiser ^)eventRaiser; lp = reinterpret_cast(GCHandle :: ToIntPtr(GCHandle :: Alloc(safe_cast (sEventRaiser)))。ToPointer(); –
このコードスニペットを形にしてコンパイルするのは難しい作業です。私が試してみると、キャストは問題ではありません。間違いの可能性は、インターフェイスの種類の定義が複数あることです。これは、.hファイルで宣言して、それを#includeしたソースファイル.NETの型識別は、名前空間と識別子の名前だけではなく、アセンブリの完全な名前も含みます。代わりにアセンブリ参照を使用して、インタフェースの定義が1つしかありません。 –
それを考えると、前にこの問題がすでに発生していました。あなたは[以前の質問](https://stackoverflow.com/q/47683677/17034)でまったく同じ間違いを犯しました。 –