2011-09-16 2 views
1

그래서 여기에 거래가 있습니다. 내가 C#을 사용하는 C# 응용 프로그램을 작동하고 있습니다.이 디렉토리는 차례대로 .lib가있는 디렉토리의 이름을 다시 가져 오는 디렉토리를 통해 반복됩니다. 다음 3 개의 폴더가있는 디렉토리 : Default.Lib, 中文文本 帧 的 文件 .lib, 我们 的 .lib.C# 관리되지 않는 함수 호출, 가능한 데이터 손실, Ascii Vs. 유니 코드, 중국어 폴더 이름

우리가 볼 수 있듯이 중국어 폴더 이름이 있습니다. 문자열은 아래에서 볼 수 있듯이 C++ 코드에 의해 메모리에 내장되어 있으며 strcat을 사용하여 메모리에 저장합니다. 그러나 컨트롤이 다시 C# 코드로 반환되면 해당 데이터의 일부가 손실 된 것처럼 보이고 남은 폴더는 처음 두 개뿐입니다. Default.Lib, 中文文本 帧 的 文件 .lib, 我们 的 .lib와 무언가가 번역에서 길을 잃으면, 나는 누군가가 가질지도 모르는 어떤 통찰력이라도 크게 감사 할 것이다. 감사.

C# 코드 조각

lock (padLock) 
      { 
       ConnectSign(service); 

       int size = MaxFileListSize * 100; 
       byte[] mem = new byte[size]; 
       string finalList; 
       int used = size; 
       int fileCount = 0; 
       string library = "*"; 
       string extension = "*"; 
       V7_FILE_LIST_TYPE type = V7_FILE_LIST_TYPE.LibraryList; 

       fixed (byte* listbytes = mem) 
       { 
        int error = NativeMethods.GetFileDirInfo(sign, type, fileServer, library, extension, &fileCount, listbytes, &used); 
        if (error != 0) 
         throw new V7ResponseException(error, sign, service, "GetFileDirInfo"); 
       } 

       finalList = Encoding.Default.GetString(mem, 0, (int)used); 

       string[] libraryArray = finalList.Split(new char[] { '\n', '\0' }, StringSplitOptions.RemoveEmptyEntries); 
       for (int i = 0; i < libraryArray.Length; i++) 
       { 
        int index = libraryArray[i].LastIndexOf(".lib", StringComparison.OrdinalIgnoreCase); 
        if (index > 0) 
         libraryArray[i] = libraryArray[i].Substring(0, index); 
        //libraryArray[i] = libraryArray[i].Trim().ToLower(CultureInfo.CurrentCulture).Replace(".lib", string.Empty); 
       } 

       return libraryArray; 
      } 

[DllImport("V7SSRpc.dll", CharSet = CharSet.Ansi, EntryPoint = "V7ssGetFileDirInfo", BestFitMapping = false, ThrowOnUnmappableChar = true)] 
      public static extern int GetFileDirInfo(string sign, V7_FILE_LIST_TYPE type, string fileServer, string library, string extension, int* fileCount, byte* files, int* bytesUsed); 

enter image description here ***************************** C++ DLL code-- ------------------------------------

//-------------------------------------------------------------------- 
    // RETURN : 
    // 
    // PARAMS : eListType 
    //    szServer 
    //    szLib 
    //    szExt 
    //    *pdwFileCnt 
    //    *pbyFileBuf 
    //    *pdwFileBufSize 
    // 
    // REMARKS: 
    // 
    BOOL CVSign::apiGetFileDirInfo(V7_FILE_LIST_TYPE eListType, LPCSTR szServer, LPCSTR szLib, LPCSTR szExt, 
              DWORD *pdwFileCnt, char *pbyFileBuf, DWORD *pdwFileBufSize) const 
    { 
     BOOL bReturn=TRUE; 
     CString sServer(szServer); 
     CString sLib(szLib); 
     CString sExt(szExt); 
     CString sFileInfo, sTemp; 
     CStringArray asFiles; 
     CFileStatus status; 
     CV7Files V7Files; 
     DWORD dwBufUsed=0; 

    // SOME OTHER LOGIC (not posted) 

     USES_CONVERSION; 

     //CoInitialize(NULL); 
     //AVIFileInit(); 

     CString sFilePath; 
     CV7SequenceFile V7Seq; 

     CV7FileInfo fileInfo; 

     // go through list of files and build the buffer with file names and other info 
     for (nFile=0; nFile<nFiles; nFile++) 
     { 
      // MORE OBSCURED LOGIC 

      sFileInfo += _T("\n"); 

      // add file info to buffer 
      int nLen = sFileInfo.GetLength(); 
      if (dwBufUsed+nLen<*pdwFileBufSize) 
      { 
       strcat(pbyFileBuf, T2CA(sFileInfo)); //<--- THIS IS THE IMPORTANT PART 
       int nTemp = sFileInfo.GetLength(); 
       dwBufUsed += nTemp; 
      } 
      else 
      { 
       *pdwFileBufSize = 0; 

       AVIFileExit(); 
       CoUninitialize(); 

       return FALSE; 
      } 
     } // end for files 

     //AVIFileExit(); 
     //CoUninitialize(); 

     *pdwFileBufSize = dwBufUsed; 

     return bReturn; 
    } // end apiGetFileDirInfo() 

enter image description here

답변

0

내가 의심 문제는 사용자가 Charset=CharSet.Ansi을 지정 했으므로 기본 마샬링 동작은 반환 된 문자열을 AN으로 변환하는 것입니다. 시. 그것은 문제를 일으킬 것입니다.

문자열 Charset=CharSet.Unicode을 지정하고 일부 문자열에 사용자 지정 마샬링을 지정할 수도 있습니다. 개별 매개 변수에 대한 문자열 마샬링 동작을 변경하는 방법에 대한 내용은 http://msdn.microsoft.com/en-us/library/s9ts558h.aspx#cpcondefaultmarshalingforstringsanchor5을 참조하십시오.

+0

그러나 바이트 배열에 대한 포인터를 처리하면 문자열 속성이이를 처리합니다. 난 그냥 불면 charset 변경 시도했다. – nagates

+0

@ 네이트 : 네 말이 맞아. 나는 오해했다. 다시 오는 데이터가 올바른 것 같습니다 (적어도 데이터 덤프가 올바르게 보입니다). 당신은'Encoding.Default.GetString'으로 데이터를 변환하고 있습니다. 'Default' 인코딩을 원하십니까? 이는 일반적으로 미국 버전의 Windows에서 8 비트 인코딩입니다. 'Encoding.Unicode' 또는'Encoding.GetEncoding()'을 http://msdn.microsoft.com/en-us/library/system.text.encoding.getencodings에 설명 된 적절한 인코딩 이름으로 시도해 볼 수도 있습니다. .aspx. –

+1

사실 C# 덤프는 요소 32에서 데이터를 잘라냅니다. 나머지는 null이므로 데이터가 손실되는 방식과 마샬링 프로세스 또는 그 중 어떤 것이 확실하지 않은지 ... 이것은 문제는 아니지만 확실하지 않습니다. strcat (pbyFileBuf, T2CA (sFileInfo)); – nagates

관련 문제