2014-12-03 23 views
0

을 사용하여 C++ char []을 C# 문자열에 마샬링 할 수 없습니다. 지금 당분간이 문제로 고생하고 있으며 저의 가장 친한 친구 중 한 명 (Google)이 나를 도와주지 않았습니다. 현재 C++ 응용 프로그램에서 보낸 메시지의 LParam에서 데이터를 가져와 사용해야하는 C# 응용 프로그램 (WinForms)을 작업 중입니다. 현재 C++ 테스트 응용 프로그램은 메시지 수신자 (C# 응용 프로그램)에서 핸들을 사용할 수 있는지 확인하고 핸들이 유효하면 메시지를 보냅니다. C++ 응용 프로그램에 대한 코드는 아래와 같습니다.Marshal.PtrToStringAuto (IntPtr)

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HWND hScreenSaver = ::FindWindow(NULL,TEXT("MessageReceiver")); //MessageReceiveris the window name of the C# application 
    if (hScreenSaver == NULL) 
    { 
     std::cout << "Handle Invalid!" << std::endl; 
     return exit(); 
    } 

    char testMessage[13] = "Test Message"; 
    ::SendMessageA(hScreenSaver, (UINT)101296, 0, (LPARAM)&testMessage); 
    return exit(); 
} 

int exit() 
{ 
    system("Pause"); 
    return 0; 
} 

나는 C++ 응용 프로그램이 올바르게 작동하고 있다고 믿습니다 (오류없이 빌드되고 실행 됨). 나는 메시지가 어떻게 보내지고 있는지 보여주기 위해 게시 할 것이라고 생각했다. 빠른 메모는 메시지 번호가 중요하지 않으며 임의로 누군가를 궁금해하는 경우를 대비하여 메시지 번호를 무작위로 선택했습니다.

메시지를 수신 내 C# 테스트 응용 프로그램은 아래에 게시 :

protected override void WndProc(ref Message m) 
{ 
    if(m.Msg == 101296) 
    { 
     if(m.LParam == IntPtr.Zero) 
     { 
      textBox1.Text = "Nothing Sent in LParam"; 
     } 
     else 
     { 
      textBox1.Text = Marshal.PtrToStringAuto(m.LParam); //This is causing the error detailed below 
     }    
    } 
    base.WndProc(ref m); 
} 

동시에이 두 응용 프로그램이 실행되는 C++ 응용 프로그램이 성공적으로 C# 응용 프로그램에게 메시지와 C# 응용 프로그램 프로세스를 보낸다 지정된 지점까지 메시지. 오류 메시지는 다음과 같습니다.

A first chance exception of type 'System.AccessViolationException' occurred in mscorlib.dll 

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 

나는 마샬을 사용하려고했습니다. 행운을 비네. 마샬링에 대한 StackOverflow의 비슷한 게시물을 보았지만 어떤 솔루션으로도 내 문제를 해결할 수 없었습니다. 다른 솔루션은 어떻게 재현 하는지를 자세히 설명하지만 다른 솔루션에서는이 오류가이 오류의 원인이라고 자세히 설명하지 않습니다.

도움을 주시면 대단히 감사하겠습니다.

답변

0

두 개의 서로 다른 응용 프로그램이 서로 다른 주소 공간을 가지고 있으므로 한 응용 프로그램의 주소가 다른 응용 프로그램에서 의미가 없을 수 있습니다. 프로세스간에 정보를 교환하는 방법에는 여러 가지가 있습니다. 그 중 하나가 WM_COPYDATA를 보냅니다. 예를 들어 here

+1

당신의 도움에 감사드립니다. '[StructLayout (LayoutKind.Sequential)] 공공 구조체 COPYDATASTRUCT { [MarshalAs (UnmanagedType :이 같은 질문을 가지고있다 다른 사람을 위해, 추가 할 한 가지는, C 번호에 COPYDATASTRUCT을 만드는 방법이다. I4)] public int dwData; [MarshalAs (UnmanagedType.I4)] public int cbData; [MarshalAs (UnmanagedType.SysInt)] 공용 IntPtr lpData; } ' 이렇게 구조를 만들었습니다. – Nibious