void WINAPI (DLL_EXP SetMessageProcessCallback)(void* pUserObject_, void (*pfUserMessageProcessFunc_)(void*,AMC_MESG*));
这是c++ dll 的一个函数,第二个参数是一个回调函数, 而这个回调函数的第二个参数是一个类的实例,请问这样的一个函数如何用c#写出来,多谢。
下面是我写的:
 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 public delegate void SetMessageCallback(IntPtr sender, [In, Out] AMC_MESG _amc); [DllImport(Constant.Dllname_amc, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
 public extern static void SetMessageProcessCallback(IntPtr pUserObject_, SetMessageCallback pfUserMessageProcessFunc_); public void ProprioWare_Load(object sender, EventArgs e)
{        
  callback1 = new SetMessageCallback(MesgProcessCallback);
  GC.Collect();
  GC.WaitForPendingFinalizers();
  SetMessageProcessCallback(this.Handle, callback1);
  GC.KeepAlive(callback1);
}
 public void MesgProcessCallback(IntPtr sender, [In,Out] AMC_MESG amc)
{ }[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class AMC_MESG
{
}
这样会报一个错误:Attempted to read or write protected memory. This is often an indication 

解决方案 »

  1.   

    下面是类AMC_MESG 的定义:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class AMC_MESG
        {
            private ushort usID;
            private byte ucSize;
            private byte ucRawMesgSize;
            private byte[] aucRawMesg = new byte[Constant.AMCMESG_MAX_SIZE];
            private byte ucScrDest;        public ushort GetMesgID() { return usID; }
            public byte GetMesgScrDest() { return ucScrDest; }
            public byte GetMesgSize() { return ucSize; }
            public byte[] GetMesgData()
            {
                byte[] tmp = new byte[aucRawMesg.Length];
                Buffer.BlockCopy(aucRawMesg, Convert.ToInt32(Constant.AMCMESG_DATA_OFFSET), tmp, 0, tmp.Length);
                return tmp;
            }
            public byte[] GetRawMesgData() { return aucRawMesg; }
            public byte GetRawMesgSize() { return ucRawMesgSize; }
            public void SetMesgID(ushort usID_) { usID = usID_; }
            public void SetMesgScrDest(byte ucScrDest_) { ucScrDest = ucScrDest_; }
            public void SetMesgSize(byte ucSize_) { ucSize = ucSize_; }        void SetMesgData(ushort usID_, byte ucScrDest_, byte[] pucData_, byte ucSize_)
            {
                SetMesgID(usID_);
                SetMesgScrDest(ucScrDest_);
                SetMesgSize(ucSize_);
                Buffer.BlockCopy(pucData_, 0, aucRawMesg, Convert.ToInt32(Constant.AMCMESG_DATA_OFFSET), Convert.ToInt32(ucSize_));
                //memcpy(aucRawMesg + AMCMESG_DATA_OFFSET, pucData_, ucSize_);
            }        void SetRawMesgData(byte[] pucRawMesg_, byte ucRawMesgSize_)
            {
                //memcpy(aucRawMesg,pucRawMesg_,ucRawMesgSize_);
                Array.Copy(pucRawMesg_, aucRawMesg, Convert.ToInt32(ucRawMesgSize_));
                ucRawMesgSize = ucRawMesgSize_;
            }        //public void operator=( ref AMC rhs)
            //{
            //    this.ucRawMesgSize = rhs.ucRawMesgSize;
            //    this.ucSize = rhs.ucSize;
            //    //memcpy(this.aucRawMesg,rhs.aucRawMesg,this.ucRawMesgSize);
            //    Buffer.BlockCopy(rhs.aucRawMesg,0,this.aucRawMesg,0,this.ucRawMesgSize);
            //    this.SetMesgID(rhs.usID);
            //    this.ucScrDest = rhs.ucScrDest;
            //} 
        }
      

  2.   

    限制级别
    参考
    http://topic.csdn.net/u/20071010/13/5197506d-1bcb-45b9-b9e1-5ad3eb2ac9ec.html
    http://topic.csdn.net/u/20071126/14/4b94abfb-4933-4a5f-96f2-2f81f4eeec69.html
      

  3.   

    请帮帮忙,我觉得是我上面的类AMC_MESG 有问题,我不知道该怎样申明定义这个类
      

  4.   

    这是c++中的
    class AMC_MESG
    {
    public:
       inline USHORT GetMesgID() { return usID; }
       inline UCHAR GetMesgScrDest() {return ucScrDest;}
       inline UCHAR GetMesgSize() { return ucSize; }
       inline UCHAR* GetMesgData(){ return aucRawMesg + AMCMESG_DATA_OFFSET; }
       inline UCHAR* GetRawMesgData() { return aucRawMesg; }
       inline UCHAR GetRawMesgSize() { return ucRawMesgSize; }
       inline void SetMesgID(USHORT usID_) { usID = usID_; }
       inline void SetMesgScrDest(UCHAR ucScrDest_) { ucScrDest = ucScrDest_; }
       inline void SetMesgSize(UCHAR ucSize_) { ucSize = ucSize_; }   void SetMesgData(USHORT usID_, UCHAR ucScrDest_, UCHAR *pucData_, UCHAR ucSize_)
       {
          SetMesgID(usID_);
          SetMesgScrDest(ucScrDest_);
          SetMesgSize(ucSize_);
          memcpy(aucRawMesg + AMCMESG_DATA_OFFSET, pucData_, ucSize_);
       }   void SetRawMesgData(UCHAR *pucRawMesg_,UCHAR ucRawMesgSize_)
       {
          memcpy(aucRawMesg,pucRawMesg_,ucRawMesgSize_);
          ucRawMesgSize = ucRawMesgSize_;
       }   void operator= (const AMC_MESG &rhs)
       {
          this->ucRawMesgSize = rhs.ucRawMesgSize;
          this->ucSize = rhs.ucSize;
          memcpy(this->aucRawMesg,rhs.aucRawMesg,this->ucRawMesgSize);
          this->SetMesgID(rhs.usID);
          this->ucScrDest = rhs.ucScrDest;
       }private:
       USHORT usID;
       UCHAR ucSize;
       UCHAR ucRawMesgSize;
       UCHAR aucRawMesg[AMCMESG_MAX_SIZE];
       UCHAR ucScrDest;
    };
      

  5.   

    除了普通方法还有这么多inline方法,一下,看看是不是真的有大虾能解决。
      

  6.   


    1、不需要完成C#的方法实现。
    如果AMC_MESG没有虚函数的话,C++中的方法调用是编译时就链接到固定地址了,C++不会调用你的C#实现的。2、如果AMC_MESG有虚函数的话,你最好放弃C#交互,或另写一个C++的DLL当中转了。
      

  7.   

    我解决这个问题了
    答案如下:
    调整AMC_MESG类:
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class AMC_MESG
        {
            [MarshalAs(UnmanagedType.U2)] 
            public ushort usID;
            [MarshalAs(UnmanagedType.I1)] 
            public byte ucSize;
            [MarshalAs(UnmanagedType.I1)] 
            public byte ucRawMesgSize;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constant.AMCMESG_MAX_SIZE)]
            public byte[] aucRawMesg = new byte[Constant.AMCMESG_MAX_SIZE];
            [MarshalAs(UnmanagedType.I1)] 
            public byte ucScrDest;
    }
    这样就可以将AMC_MESG的实例作为callback的参数传入了