none
C#调用C++ DLL,C++ DLL向C#发消息。 RRS feed

  • 问题

  •  

     

    描述:C#调用C++ DLL的方法,C++ DLL向C#发送消息(SendMessage)。昨天写的代码,当时没有异常,今天重新执行程序出现异常。

    目前从C++ DLL向C#发送的消息也可以收到,就是执行后有异常。

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    异常:Message: 作为 String 传入的指针一定不能位于进程地址空间的低位 64K。

             StackTrace = "   在 System.String..ctor(SByte* value)\r\n   在 System.StubHelpers.CSTRMarshaler.ConvertToManaged(IntPtr cstr)\r\n   在 AsstGUI.FrmMain.Get_Msg_Test(IntPtr hwnd)\r\n   在 AsstGUI.FrmMain.FrmMain_Load(Object sender, EventArgs e) 位置 D:\\workspace

             Source = "mscorlib"

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    代码:

    C#

    [DllImport("Spy.dll",EntryPoint="Get_Msg_Test",CallingConvention =CallingConvention.Cdecl)]
            public static extern string Get_Msg_Test(IntPtr hwnd);
    
    private void FrmMain_Load(object sender, EventArgs e)
            {
                try
               {
    	         Get_Msg_Test(this.Handle);
                }
                catch (System.Exception ex)
                {
     	          //程序收到C++发过来的消息后,此处有异常
                }
            }
    
            //用户自定义消息
            public const int WM_USER = 0x0400;
            public const int WM_TEST = WM_USER + 1;
    
    protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    //旺旺最后一条聊天记录消息
                    case WM_TEST:
                        LParamDataSruct lparam = (LParamDataSruct)m.GetLParam(typeof(LParamDataSruct));
                        String msg  = lparam.lParamData;//此处能得到C++ DLL发送的消息内容
                        break;
                    default:
                        break;
                }
                base.WndProc(ref m);
            }
    
            /// <summary>
            /// Message 接收GetLParam方法返回值
            /// LParamData返回内容与LParamData结构体相同
            /// </summary>
            public struct LParamDataSruct
            {
                public String lParamData;
            }
    

    C++
    #define WM_TEST WM_USER+1//自定义消息
    
    struct LParamDataSruct
    {
    public:
    	char* lParamData;       //要发送的信息
    };
    
    //hwnd为C#窗体的句柄
    extern "C" __declspec(dllexport) bool Get_Msg_Test(HWND hwnd)
    {
    	LParamDataSruct lparam;
    	char* test = "This is test MSG 哈哈。";
    	lparam.lParamData = test;
    
    	::SendMessage(hwnd,WM_TEST,wPARAM,(LPARAM)&lparam);
    	return true;
    }
    

    折腾了好久都解决不了,这个问题第一次见。恳请帮助!
    2012年1月21日 8:34

答案

  • [DllImport("Spy.dll",EntryPoint="Get_Msg_Test",CallingConvention =CallingConvention.Cdecl)]
            <strong>public static extern <em>string</em> Get_Msg_Test(IntPtr hwnd);</strong>
    
    


    发现问题了。C++ Get_Msg_Test原形返回值班是bool,而在C#导入时返回值回值为string。^_^
    不过这个异常提示真的让我无语听,

    异常:Message: 作为 String 传入的指针一定不能位于进程地址空间的低位 64K。

     

    另外发现在用Marshal.PtrToStringAnsi(m.LParam);获得C++传过来的值更方便。^_^

    2012年1月21日 13:37

全部回复

  • [DllImport("Spy.dll",EntryPoint="Get_Msg_Test",CallingConvention =CallingConvention.Cdecl)]
            <strong>public static extern <em>string</em> Get_Msg_Test(IntPtr hwnd);</strong>
    
    


    发现问题了。C++ Get_Msg_Test原形返回值班是bool,而在C#导入时返回值回值为string。^_^
    不过这个异常提示真的让我无语听,

    异常:Message: 作为 String 传入的指针一定不能位于进程地址空间的低位 64K。

     

    另外发现在用Marshal.PtrToStringAnsi(m.LParam);获得C++传过来的值更方便。^_^

    2012年1月21日 13:37
  • Hi m4wayne,

    龙年伊始你就如此给力啊, 现在你可以将自己的回复mark成answer了. :)
    祝你龙年快乐, 
    Leo Liu [MSFT]
    MSDN Community Support | Feedback to us
    2012年1月24日 5:46
    版主