그래서 여기에 거래가 있습니다. 내가 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);
***************************** 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()
그러나 바이트 배열에 대한 포인터를 처리하면 문자열 속성이이를 처리합니다. 난 그냥 불면 charset 변경 시도했다. – nagates
@ 네이트 : 네 말이 맞아. 나는 오해했다. 다시 오는 데이터가 올바른 것 같습니다 (적어도 데이터 덤프가 올바르게 보입니다). 당신은'Encoding.Default.GetString'으로 데이터를 변환하고 있습니다. 'Default' 인코딩을 원하십니까? 이는 일반적으로 미국 버전의 Windows에서 8 비트 인코딩입니다. 'Encoding.Unicode' 또는'Encoding.GetEncoding()'을 http://msdn.microsoft.com/en-us/library/system.text.encoding.getencodings에 설명 된 적절한 인코딩 이름으로 시도해 볼 수도 있습니다. .aspx. –
사실 C# 덤프는 요소 32에서 데이터를 잘라냅니다. 나머지는 null이므로 데이터가 손실되는 방식과 마샬링 프로세스 또는 그 중 어떤 것이 확실하지 않은지 ... 이것은 문제는 아니지만 확실하지 않습니다. strcat (pbyFileBuf, T2CA (sFileInfo)); – nagates