Как я могу прочитать fstream в LPSAFEARRAY?

Я пытаюсь вызвать метод на управляемой DLL в C ++. Одним из параметров является байтовый массив, который библиотека импортирует в LPSAFEARRAY. Массив байтов / LPSAFEARRAY предназначен для содержимого файла. Как я могу прочитать файл в LPSAFEARRAY для передачи в метод?

Вот подпись функции из сгенерированного файла заголовка библиотеки:

virtual HRESULT STDMETHODCALLTYPE AlterDocument(
LPSAFEARRAY document/*[in]*/,
LPSAFEARRAY* pRetVal/*[out,retval]*/) = 0;

Второй параметр — это еще один байтовый массив, который мне нужно будет использовать, когда он вернется из метода.

2

Решение

Вы можете изначально создать SAFEARRAYBOUND и инициализировать его как массив C, например SAFEARRAYBOUND sabdBounds[2] = { {10, 0}, {20, 0\} }; а затем использовать SafeArrayCreate (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221234(v=vs.85).aspx) с соответствующим типом и размерами, чтобы получить необходимые LPSAFEARRAY,

Обновить:

Вот фрагмент кода, который показывает, как создать LPSAFEARRAYКак вы можете видеть, я нахожу размер файла перед созданием массива, чтобы иметь возможность напрямую считывать данные в него, вы также можете сохранить содержимое файла в некотором промежуточном буфере, а затем создать SAFEARRAYBOUND потом:

    #include <Windows.h>
#include <fstream>
#include <cstdlib>

int main(int argc, char** argv)
{
std::streampos fileSize = 0;
std::ifstream inputFile("file.bin", std::ios::binary);
fileSize = inputFile.tellg();
inputFile.seekg( 0, std::ios::end );
fileSize = inputFile.tellg() - fileSize;
SAFEARRAYBOUND arrayBounds[1] = { {fileSize, 0}}; // You have one dimension, with fileSize bytes
LPSAFEARRAY safeArray = SafeArrayCreate(VT_I1, 1, arrayBounds);
SafeArrayLock(safeArray);
char* pData = reinterpret_cast<char*>(safeArray->pvData); // This should be the pointer to the first element in the array, fill in the data as needed
// Do your stuff
SafeArrayUnlock(safeArray);
SafeArrayDestroy(safeArray);
inputFile.close();
}
1

Другие решения

Если у вас есть ATL:

ifstream in(...);
CComSafeArray<BYTE> fileContents;

for (ifstream::traits_type::int_type ch = in.get(); ch != ifstream::traits_type::eof(); ch = in.get())
fileContents.Add(ch);

managedObject->AlterDocument(fileContents, ...);

Если у вас нет ATL, вам придется напрямую манипулировать SAFEARRAY без оболочки CComSafeArray.

0

Вариант может быть, чтобы получить ifstream размер, а затем создать SAFEARRAY с правильным размером для хранения всего содержимого файла, а затем read() содержимое файла в SAFEARRAY объем памяти.

Код может быть примерно таким (с помощью удобного ATL::CComSafeArray обертка):

// Open the file
ifstream inFile;
inFile.open("<<filename>>", ios::binary);
if (! inFile.is_open())
// ... error

// Get length of file
inFile.seekg(0, ios::end);
const int length = inFile.tellg();
inFile.seekg(0, ios::beg);// Allocate SAFEARRAY of proper size.
// ATL::CComSafeArray<T> is a convenient C++ wrapper on raw SAFEARRAY structure.
CComSafeArray<BYTE> sa;
HRESULT hr = sa.Create(length);
if (FAILED(hr))
// ... error

// Read data into the safe array
BYTE * dest = &(sa.GetAt(0));
inFile.read(reinterpret_cast<char*>(dest), length);

// Close the stream
// (or let the destructor automatically close it when inFile goes out of scope...)
inFile.close();
0
По вопросам рекламы [email protected]