2

C++ でマネージド DLL のメソッドを呼び出そうとしています。パラメータの 1 つはバイト配列で、ライブラリのインポートによって LPSAFEARRAY に変換されます。バイト配列/LPSAFEARRAY は、ファイルの内容であることを意図しています。ファイルを LPSAFEARRAY に読み込んでメソッドに渡すにはどうすればよいですか?

生成されたライブラリ ヘッダー ファイルの関数シグネチャは次のとおりです。

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

2 番目のパラメーターは、メソッドから戻るときに使用する必要がある別のバイト配列です。

4

3 に答える 3

1

最初に を作成しSAFEARRAYBOUND、C 配列のように初期化SAFEARRAYBOUND sabdBounds[2] = { {10, 0}, {20, 0\} };できますSafeArrayCreate。必要な を取得するための適切なタイプと寸法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();
    }
于 2012-10-23T16:03:41.387 に答える
0

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がない場合は、CComSafeArrayラッパーを使用せずにSAFEARRAYを直接操作する必要があります。

于 2012-10-23T16:13:50.740 に答える
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();
于 2012-10-23T16:33:48.573 に答える