문제

나는 상황이 나를 감싸는 네이티브 C++DLL C++을 위한 최종 사용하여 C#에서.

거기에 몇 가지의 콜백 함수를 일으키는 문제입니다.특히,나는 다음과 같은 예외:

처리되지 않은 형식의 예외가 '시스템이다.런타임입니다.InteropServices.InvalidOleVariantTypeException' 에서 발생 ToadWrapTest.dll

추가 정보:지정된 OLE 변형이 잘못되었습니다.

이 라인의 코드(C++):

public delegate int ManagedCallbackFunction (Object^ inst, const Object^ data);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);

ManagedCallbackFunction^ m_callbackFn;

int intermidiaryCallback(void * pInstance, const void * pData)
    {   
        void* temp = (void*)pData;
        System::IntPtr ip1 = IntPtr(pInstance);
        System::IntPtr ip2 = IntPtr(temp);
        Object^ oInst = Marshal::GetObjectForNativeVariant(ip1);
        Object^ oData = Marshal::GetObjectForNativeVariant(ip2);
        //invoke the callback to c#
        //return m_callbackFn::Invoke(oInst, oData);
        return 0;
    };

이유는 내가 만들이"중개 콜백"었을 회피하려는 잘못된 변형을 제외되는 것을 때 발생했을 직접 지도하에서 대리인 C#어는 C++코드입니다.으로도 작업,주위에 내가 선언하는 대리인에서는 C#측면과 전달하는 funcptr C++/CLI 래퍼입니다.나는 다음을 전달 중개 funcptr 어는 C++고 데이지 체인 전화를 함께.

내가 무엇을 알고 있는 모든 작품에서는 네이티브 C++에서 세계입니다.문제입니다 매핑 void*관리되는 세계입니다.다음 코드는 native C++버전의 callback:

int (*CallbackFunction) (void *inst, const void *data);

사람이 여기에 도움이 될 수 있습니다,정말 감사드리겠습니다.

도움이 되었습니까?

해결책

Pinstance와 Pdata가 정말 변형입니까? 그들이 있다면, 나는 당신의 콜백 기능이보다 강력하게 입력 될 것으로 기대합니다.

int (*CallbackFunction)(VARIANT *inst, VARIANT *data);

이 경우 코드에서 실제를 볼 수 있어야합니다. 변종 손으로 확인합니다. 실제로 변형을 얻지 못한다면 (즉, 실제로 무효 * 포인터를 얻는다), 고유 한 의미가 없기 때문에 C# 객체로 바꾸려고해서는 안됩니다. 그들은 intptr로 통과해야합니다. 다른 유형의 고유 한 의미가 있어야한다는 것을 알고 있다면 적절한 유형으로 마샬링해야합니다.

다른 팁

큰 감사를 받침대에 하나입니다!나는 게시 최종 솔루션은 아래 사람은 누구나 다른 사람과 거래하는 제 3 자 재미있는 이처럼 하나입니다!을 주시기 바랍 비평,나와 같은 수행하지 않을 최적화하는 코드입니다.이 여전히 수 있습을 원형 교차로는 솔루션입니다.

첫째,콜백 함수가 되었:

public delegate int ManagedCallbackFunction (IntPtr oInst, IntPtr oData);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);
ManagedCallbackFunction^ m_callbackFn;

큰 소품이다.그것은 그냥 평범한 작동하지 않을 시도하는 경우 캐스팅에서 무효*직접 개체^.를 사용하 IntPtr 및 내 중개 callback:

int intermidiaryCallback(void * pInstance, const void * pData)
{   
    void* temp = (void*)pData;
    return m_callbackFn->Invoke(IntPtr(pInstance), IntPtr(temp));
};

우리가 마지막으로 작동하는 모델에서 C#쪽으로 몇 마사지기의 개체:

public static int hReceiveTestMessage(IntPtr pInstance, IntPtr pData)
{
   // provide object context for static member function
   helloworld2 hw = (helloworld2)GCHandle.FromIntPtr(pInstance).Target;
   if (hw == null || pData == null)
   {
      Console.WriteLine("hReceiveTestMessage received NULL data or instance pointer\n");
      return 0;
   }

   // populate message with received data
   IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataPacketWrap(pData)));
   DataPacketWrap dpw = (DataPacketWrap)GCHandle.FromIntPtr(ip2).Target;
   uint retval = hw.m_testData.load_dataSets(ref dpw);
   // display message contents
   hw.displayTestData();

   return 1;
}

내가 언급"마사지"기 때문에 대리인 한정하지 않고 이 콜백 함수하고 내가 무엇인지 모르체 pData 될 때까지 실행 시간(에서 대표 POV).이 문제 때문에,나는 몇 가지 추가 작업을 수행과 pData 개체입니다.저는 기본적으로 과부하가 생성자 내에서 래퍼를 받아들이는 IntPtr.코드가 제공됩를 위한 전체"clarity":

DataPacketWrap (IntPtr dp)
{ 
DataPacket* pdp = (DataPacket*)(dp.ToPointer());
m_NativeDataPacket = pdp;
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top