2016-12-09 15 views
-3

C++에서 C#으로 P/호출하는 데 몇 가지 DLL을 개발했습니다. 그러나 하드 실시간 환경에서 작업하며 P/Invoke는 특정 작업을 수행하기에는 너무 느리다는 것을 증명했습니다.C/C# interop에서 메모리 매핑 및 P/Invoke 성능

#include "stdafx.h" 

#define BUF_SIZE 256 
TCHAR szName[] = TEXT("MyFileMappingObject"); 
char* pcTest = "Message from C++"; 

int _tmain() 
{ 
    HANDLE hMapFile; 
    LPCTSTR pBuf; 

    hMapFile = CreateFileMapping(
       INVALID_HANDLE_VALUE, 
       NULL, 
       PAGE_READWRITE, 
       0, 
       BUF_SIZE, 
       szName); 

    if (hMapFile == NULL) { 
     _tprintf(TEXT("Could not create file mapping object (%d).\n"), GetLastError()); 
     return 1; 
    } 

    pBuf = (LPTSTR)MapViewOfFile(
       hMapFile, 
       FILE_MAP_ALL_ACCESS, 
       0, 
       0, 
       BUF_SIZE); 

    if (pBuf == NULL) { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); 
     CloseHandle(hMapFile); 
     return 1; 
    } 

    CopyMemory((PVOID)pBuf, pcTest, (strlen(pcTest) * sizeof(char*))); 

    std::cin.get(); 

    UnmapViewOfFile(pBuf); 
    CloseHandle(hMapFile); 

    return 0; 
} 

내가의 코드를 적용 :

그래서 나는 (아마도) P/호출에 내 테스트 기간 동안 빠른 대안, 사물의 C++ 쪽이 너무 초라한 보이지 않았다으로 메모리 매핑을 가로 질러왔다 여기 :

static void Main(string[] args) 
    { 
     MemoryMappedFile pagedMemoryMap = MemoryMappedFile.OpenExisting("MyFileMappingObject", MemoryMappedFileRights.FullControl); 

     using (MemoryMappedViewAccessor fileMap = pagedMemoryMap.CreateViewAccessor()) 
     { 
      var array = new byte[256]; 
      fileMap.ReadArray(0, array, 0, 16); //Take notice on this line 
      var text = Encoding.ASCII.GetString(array); 
      Console.WriteLine(text); 
     } 

     Console.ReadKey(); 
    } 
:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx

그리고 여기는 C# 쪽입니다

의도 한대로 작동하지만 여기에 문제가 있습니다. ReadArray 메서드의 바이트 배열 길이가 고정 된 크기입니다. 내 실제 응용 프로그램에서 실제 문자열의 길이를 다른 공유에 써야한다고 가정하고 문자열 값을 읽는 데 사용하지만 너무 복잡합니다. 실제 응용 프로그램에서 C++에서 실제로 읽은 것이 구조체 배열 (주로 문자열 만 포함) 인 것을 고려하면 메모리 매핑에서 성능상의 이득을 얻을 수 있습니까? 나는 의도 된 결과가 없을 수도있는 대안을 가진 안정된 코드 (느리지 만)를 부풀리기위한 어떠한 의도도 없으므로,이 접근법에 실질적인 이익이 있습니까? 더 나은 대안이 있습니까?

+1

C#은 하드 실시간 환경에는 적합하지 않습니다. 가비지 컬렉터가 타이밍을 놓치게됩니다. 사실 페이징과 인터럽트 처리가 타이밍을 놓치기 때문에 Windows는 하드 실시간 환경에 적합하지 않습니다. 소프트 실시간/거의 실시간은 다른 이야기입니다. –

+0

물론, 우리는 1 : 1의 비율을 가지려하지 않습니다. C# 부분은 시각화 전용이며, 값이 더 높은 수준에서 몇 가지 업데이트가 누락되면 중요하지 않은 방식으로 지속적이고 신속하게 업데이트됩니다. 그러나 소프트 실시간 에뮬레이터를 사용하여 모든 것을 실행하면 정상적으로 작동하지만 일단 실제 하드웨어에 연결하면 문제가 실제로 발생합니다. – makoshichi

답변

2

메모리 맵 파일은 프로세스간에 데이터를 공유하는 데 적합합니다. 같은 메모리 공간에있는 모듈간에 공유하는 것은 무의미합니다.

일반적인 방식으로 데이터 구조를 참조 클래스 유형으로 정의한 다음 고정하십시오. 이제 C++은 일반 포인터 액세스를 사용하여 직접 데이터 구조에 액세스 할 수 있습니다.

카운트 된 문자열은 메모리 매핑 된 파일에서와 마찬가지로 고정 배열에서 작동하지만 커널을 호출 할 필요가 없다는 점이 다릅니다.

+0

개체 고정에 대한 제안이 마음에 들었습니다. 나는 월요일에 그것을 시험해보고 결과를보고 할 것이다. – makoshichi