Mega Code Archive

 
Categories / Delphi / System
 

How to do a SafeArray Access with a DLL for Variants (OLE)

Title: How to do a SafeArray Access with a DLL for Variants (OLE) Question: I had to write some safecall procedures in Delphi for an excisting DLL in C++. I didn't find any example on the Net nor many documentation about it. So it took me some time but here is the code that finally did the job. In this procedure I show you how to write string arrays, matrix arrays or blob-data (like graphics) Thx to Luc for the C++ support Now there is at least one document about SafeCalls in Delphi ;-) Answer: This here is a "cut-out" from demo i wrote to use the DLL demanding some safecalls. I added the code how to create Strings, matrix-arrays or blob safecalls I replaced DLL-specific code with xxxxxxx. Up to you to replace it with your code. // --------------------------------------------------------------------------- // OLE SAFECALL DEMO ! // --------------------------------------------------------------------------- procedure TForm_OLEDemo.SB_ActivateClick(Sender: TObject); var MyConnect : Ixxxxxx; // contains pointer to the Interface dispatch // this depends on your DLL-interface // correct Ixxxxxx by your Interface data. // See also further in the code for changing MyHandle : THandle; // the handle for passing the info pSafeHeader : PSafeArray; // needed for the SafeCall to the DLL MyHeader : OleVariant; // will contain an array of strings pSafeMatrix : PSafeArray; // needed for the SafeCall to the DLL MyMatrix : Variant; // will contain an matrix array of variants MyFileHandle : integer; // to calculate the size iBytesRead : integer; // unused return parm MyFileSize : integer; // needed for the byte calc MyPtr : pointer; MyRGSA_bound : array[0..0] of TSafeArrayBound; // needed for the SafeCall pSafeBlob : PSafeArray; // needed for the SafeCall to the DLL MyFileToRead : Widestring; begin MyFileToRead := 'C:\image.jpg'; // as an example // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PREPARING SOME VARIABLES - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // AN ARRAY - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyHeader := VarArrayCreate([0,2], VT_BSTR); MyHeader[0] := 'title 1'; MyHeader[1] := 'title 2'; MyHeader[2] := 'title 3'; pSafeHeader := PSafeArray(TVarData(MyHeader).VArray); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // A MIXED ARRAY - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyMatrix := VarArrayCreate([0, 1, 0, 2],VT_VARIANT) ; MyMatrix[0,0] := 1; // an integer MyMatrix[0,1] := 'some text'; // text MyMatrix[0,2] := now(); // date MyMatrix[1,0] := 1; MyMatrix[1,1] := 'more text'; MyMatrix[1,2] := now(); pSafeMatrix := PSafeArray(TVarData(MyMatrix).VArray); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // BLOB INFO (data, pictures, ...) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyFileHandle := FileOpen(MyFileToRead, fmOpenRead); MyFileSize := FileSeek(MyFileHandle,0,2); FileSeek(MyFileHandle,0,0); MyRGSA_bound[0].lLbound := 0; // - - - - - - - - - MyRGSA_bound[0].cElements := MyFileSize; // This is tricky ! pSafeBlob := SafeArrayCreate(VT_I1,1, MyRGSA_bound); // - - - - - - - - - SafeArrayAccessData(pSafeBlob,MyPtr); iBytesRead := FileRead(MyFileHandle, MyPtr^, MyFileSize); FileClose(MyFileHandle); SafeArrayUnAccessData(pSafeBlob); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Create OleServer Object - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - try MyConnect := CreateOleObject('***YOUR OWN CALL***') as Ixxxxxx;; except ShowMessage('Could not create an API object.'#13 'Check if the DLL has been registered on this machine?'); Exit; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Activate & Handle capturing - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyHandle := MyConnect.OpenDLLHandle(xxxxxx); // * * * * * * * * * * * * * * // Now you can use the pSafeHeader, pSafeMatrix and pSafeBlob in the // procedures of your DLL that demands these safecalls to exchange // the prepared data. // * * * * * * * * * * * * * * MyConnect.CloseDLLHandle(MyHandle,xxxxxxx); end;