Я ненавижу спрашивать это, потому что я думаю, что это должно быть очень тривиально. Но как человек, привыкший к языкам высокого уровня, это настоящая проблема.
Я получил программу на C ++, которая использует PDFium для генерации изображения в PDF. И у меня есть программа на C #, которая взаимодействует с программой на C ++ через Named Pipes. Файл PDF (который сохраняется как байтовый массив) передается по каналу. И вот моя проблема.
На 374-й позиции потока находится байт NUL (00), и я слишком глуп, чтобы каким-то образом получить данные после него.
Вот мой код:
LPTSTR lpszPipename2 = TEXT("\\\\.\\pipe\\myNamedPipe2");
hPipe2=CreateFile(lpszPipename2, GENERIC_READ, 0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(ReadFile( hPipe2, chBuf, dwBytesToRead, &cbRead, NULL))
{
PDFData = chBuf;
}
dwBytes для чтения — это размер файла, а cbRead показывает правильное число. Но PDFData содержит только первые 373 байта. Я проверил, что данные за 373-й позицией есть в Immediate Window, я просто не знаю, как их обработать.
Я должен поместить данные в массив символов.
Как я уже сказал, я думаю, что это очень тривиально. Но хотя я знаю, откуда возникла проблема, я просто не знаю, как ее решить.
Большое спасибо и всего наилучшего
Майкл
Изменить: C # -Код. Это все, но идеально. Но я уверен, что эта проблема на стороне C ++.
public void SendRawData(byte[] data)
{
while (clientse == null || clientse.stream == null)
{ }
if (clientse.stream.CanWrite)
{
clientse.stream.Write(data, 0, data.Length);
clientse.stream.Flush();
}
}
private void ListenForClients()
{
while (true)
{
clientHandle = CreateNamedPipe(this.pipeName, DUPLEX | FILE_FLAG_OVERLAPPED, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
//could not create named pipe
if (clientHandle.IsInvalid)
return;
int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);
//could not connect client
if (success == 0)
return;
clientse = new Client();
clientse.handle = clientHandle;
clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
if (ClientType == 0)
{
Thread readThread = new Thread(new ThreadStart(Read));
readThread.Start();
}
}
}
«Решение»:
На самом деле это никогда не было настоящей проблемой. Я только что пересек мои провода. В то время как chBuf выглядел после копирования его в PDFData или когда я читал, его значение VS, чтобы иметь только те 373 байта. Все ~ 20 килобайт были скопированы в эту позицию.
Я знал это, но я не понимал, как источники PDFium должны знать, что, если строка заканчивается после 373 символов.
Ну … источники в PDFium знают это, потому что я должен передать длину. Который был определен
size_t len = PDFData.length();
и поэтому было, конечно, только 373 байта.
Нулевой символ '\0'
используется C / C ++ для завершения char*
строки. Таким образом, любая библиотечная функция (т.е. strlen()
, strncpy()
, так далее) будет использовать нулевой символ в качестве неявного индикатора конца строки. Ваш код явно делает это где-то. Вместо этого используйте что-то более похожее memcpy()
или std::vector<char>
с явной длиной данных.
Посмотри на string:assign
(http://www.cplusplus.com/reference/string/string/assign/)
Оператор присваивания строки из char *
использует соглашение о конце строки в стиле C Вам нужен «буфер» assign
вызов:
string& assign (const char* s, size_t n);
Это будет включать в себя любые NUL
s.
При этом вектор байтов действительно может быть лучшим выбором.
На самом деле это никогда не было настоящей проблемой. Я только что пересек мои провода. В то время как chBuf выглядел после копирования его в PDFData или когда я читал, его значение VS, чтобы иметь только те 373 байта. Все ~ 20 килобайт были скопированы в эту позицию. Я знал это, но я не понимал, как источники PDFium должны знать, что, если строка заканчивается после 373 символов.
Ну … источники в PDFium знают это, потому что я должен передать длину. Который был определен
size_t len = PDFData.length ();
и поэтому было, конечно, только 373 байта.
Извини, что беспокоил тебя этим