C#接口。
[ComImport, Guid("7C587563-4F3C-45cb-8ECD-6AE604D0527D"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
    public interface INotifyCallback
    {
        void MyEventCallback(int nMSG);
        void MyEventCallback2(int nMSG);
        
    }上面是C#接口,我想实现的是将这个接口的一个实例当做参数传递给Dll,实现回调。C代码中定义了一个类似的接口,
interface INotifyCallback
{
virtual void __stdcall MyEventCallback(int nMSG);
virtual void __stdcall MyEventCallback2(int nMSG);
     
};
可是交给C的DLL去处理这个接口时,一调用接口的方法就会崩溃。
恼火啊。
急切,,谢啦。

解决方案 »

  1.   

    我是这样把接口的实例传过去的。这是一个实现类。
    public class Test : INotifyCallback
        {
            public void MyEventCallback(int nMSG)
            {
                MessageBox.Show("call back la");
            }
         。
         。
        }
    这个是把接口实例传过去。。 其中 PhoneLib 是我从dll内部获取到的接口。
    PhoneLib.RegNotify(new Test());
      

  2.   

    碰到类似的情况,一般建议用C++/CLI实现中间层,否则直接想在C#和C++之间交互会有些麻烦.
    你不能直接传对象,只能单个设置函数指针.         public delegate void CallbackDelegate(int msg);
             public interface INotifyCallback
            {
                void MyEventCallback(int nMSG);
                void MyEventCallback2(int nMSG);
             }
            public class Test : INotifyCallback
            {            #region INotifyCallback Members            public void MyEventCallback(int nMSG)
                {
                    
                }            public void MyEventCallback2(int nMSG)
                {
                    
                }            #endregion
            }        static void Main(string[] args)
            {
                INotifyCallback inc = new Test();
                CallbackDelegate del1 = inc.MyEventCallback;
                CallbackDelegate del2 = inc.MyEventCallback2;            IntPtr funcPointer1 = Marshal.GetFunctionPointerForDelegate(del1);
                IntPtr funcPointer2 = Marshal.GetFunctionPointerForDelegate(del1);            PhoneLib.RegNotify1(funcPointer1);
                PhoneLib.RegNotify2(funcPointer2);
            }
      

  3.   

    IntPtr funcPointer1 = Marshal.GetFunctionPointerForDelegate(del1);
    这句会有个System.MethodAccessException
    Attempt to access the method failed.我这个是wince 平台,呵呵,,
      

  4.   


    Sorry,忘了两句关键的,你要让GC保证不去回收两个委托,另外Compact Framework是支持的. IntPtr funcPointer1 = Marshal.GetFunctionPointerForDelegate(del1);
     GC.KeepAlive(funcPointer1);
     IntPtr funcPointer2 = Marshal.GetFunctionPointerForDelegate(del2);
     GC.KeepAlive(funcPointer2);
      

  5.   

     IntPtr funcPointer1 = Marshal.GetFunctionPointerForDelegate(del1);
     GC.KeepAlive(del1);//不是funcPointer11
     IntPtr funcPointer2 = Marshal.GetFunctionPointerForDelegate(del2);
     GC.KeepAlive(del2);
      

  6.   


    复制的你的代码,运行就会有这个异常。 在GetFunctionPointerForDelegate的时候就异常了, Methodaccessexception,应该是手机上不支持??
      

  7.   

    Marshal.GetFunctionPointerForDelegate Method 
    Silverlight Other Versions .NET Framework 4.NET Framework 3.5.NET Framework 3.0.NET Framework 2.0
    This type has a SecurityCriticalAttribute attribute, which restricts it to internal use by the .NET Framework for Silverlight class library. Application code that uses any member of this type throws a MethodAccessException.
    [SECURITY CRITICAL] Converts a delegate into a function pointer callable from unmanaged code.
    呵呵,这个方法限定了内部使用,wince 不得行。。
      

  8.   

    如果是这样的话,暂时想不到最佳的方法了.实在无法让C++代码回调,就尝试在C#这边开线程轮询等待消息.
    轮询的方式可以是让C++通过Event通知消息,C#这边WaitForSingleObject等待Event被Set,然后去接收消息.WaitForSingleObject,这个是CE上面Coredll.dll里的系统函数,需要做PInvoke.
      

  9.   

    你C#中定义为IDispatch,而C中却是一个光秃秃的接口,两个接口的布局完全不同了。
    C#的INotifyCallback相当于IUnknow,紧跟着IDispatch,再跟着MyEventCallback;你在C调用第一个函数,等于调用到IUnknown的QueryInterface。建议C和C#的接口都继承IUnknown或IDispatch:interface INotifyCallback : IDispatch  //<---
    {
    virtual void __stdcall MyEventCallback(int nMSG);
    virtual void __stdcall MyEventCallback2(int nMSG);
    };
    extern "C"
    {
    _declspec(dllexport) VOID _stdcall RegNotify(INotifyCallback* p)
    {
    p->MyEventCallback(123);
    }
    }[ClassInterface(ClassInterfaceType.None)]
    public partial class Form1 : Form, INotifyCallback
    {
        public Form1()
        {
            InitializeComponent();
            RegNotify(this);
        }
        public void MyEventCallback(int nMSG) { MessageBox.Show("hello" + nMSG); }
        public void MyEventCallback2(int nMSG){}    [DllImport("Mydll.dll")]
        static extern bool RegNotify([MarshalAs(UnmanagedType.Interface)]INotifyCallback a);}
    [InterfaceType( ComInterfaceType.InterfaceIsIDispatch)]  //<---
    interface INotifyCallback
    {
        void  MyEventCallback(int nMSG);
        void  MyEventCallback2(int nMSG);
    }
      

  10.   


    现把分给你啦。
    回调一般是注册到线程里面去, 可是线程里面一调用就崩溃了.
    注册的时候还没起线程,这时候直接调用回调就没有问题。 如下:int CCommunication::RegisterEventCallback(IEventCallback* pcb)
    {
    m_pEventCallback = pcb;
            //m_pEventCallback->EventCallback(33); // 可以
    //CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, (void*)pcb, 0, NULL); //不行
    return 0;
    }不知道是为啥了。。