⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 0,1410,22016,00.html

📁 C++builder学习资料C++builder
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<br><tt>\{</tt> 

<br><tt>&nbsp;&nbsp; // Method 1</tt> 

<br><tt>&nbsp;&nbsp; TArrayDimT&lt;2> Dim_1(20, 10);</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayT&lt;<b>long</b>, VT_I4, 2> Array2D_1(Dim_1);</tt> 

<p><tt>&nbsp;&nbsp; // Method 2</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayDim2 Dim_2(20, 10);</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayLong2 Array2D_2(Dim_2);</tt> 

<p><tt>&nbsp;&nbsp; // Method 3</tt> 

<br><tt>&nbsp;&nbsp; SAFEARRAYBOUND sabdBounds&#91;2&#93; = \{ \{10, 0\}, \{20, 0\} 

\};</tt> 

<br><tt>&nbsp;&nbsp; LPSAFEARRAY lpsaArray = SafeArrayCreate(VT_I4, 2, 

sabdBounds);</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayLong2 Array2D_3(lpsaArray);</tt> 

<p><tt>&nbsp;&nbsp; <b>return</b> 0;</tt> 

<br><tt>\}</tt> 

<br><tt>//---------------------------------------------------------------------------</tt> 

<p>The first method provides all the template arguments for TArrayDimT 

and TSafeArrayT. The second method uses typedefs for commonly used arrays. 

See the bottom of safearry.h for these typedefs among others. The third 

method first constructs a SAFEARRAY using Win32&nbsp; and then attaches 

the SAFEARRAY to a TSafeArrayLong2. Each of the three SafeArrays are destroyed 

in the destructor of TSafeArrayT when they go out of scope, which leads 

us to the next topic. 

<p><font size=+2>Accessing TSafeArrayT Elements</font> 

<br>Modifying the elements of the array is very simple. The index of operator 

(<b>&#91;&#93;</b>) has been overloaded for this purpose. This operator returns 

a reference to a TSAAccessorT object that can also has the index of operator 

overloaded so that multidimensional arrays can be accessed by a series 

of index of operations. However, there is a small but significant bug in 

the destructor of TSAAccessorT that makes it unusable for multidimensional 

arrays. In safearry.h starting on line 220 is the following: 

<p><tt>~TSAAccessorT()</tt> 

<br><tt>&nbsp;\{</tt> 

<br><tt>&nbsp;&nbsp; <b>if</b> (m_Alloc) \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp; <b>delete</b>&#91;&#93; m_Indices;</tt> 

<br><tt>&nbsp;&nbsp; \}</tt> 

<br><tt>&nbsp;\}</tt> 

<p>This should read: 

<p><tt>~TSAAccessorT()</tt> 

<br><tt>&nbsp;\{</tt> 

<br><tt>&nbsp;&nbsp; <b>if</b> (m_Alloc) \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp; m_Indices--;</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp; <b>delete</b>&#91;&#93; m_Indices;</tt> 

<br><tt>&nbsp;&nbsp; \}</tt> 

<br><tt>&nbsp;\}</tt> 

<p>Now, the following program will not give an access violation. 

<p><tt>//---------------------------------------------------------------------------</tt> 

<p><tt><font color="#009900">#include &lt;vcl.h></font></tt> 

<br><tt><font color="#009900">#include &lt;windows.h></font></tt> 

<br><tt><font color="#009900">#include &lt;safearry.h></font></tt> 

<br><tt><font color="#009900">#pragma hdrstop</font></tt> 

<p><tt>//---------------------------------------------------------------------------</tt> 

<p><tt><font color="#009900">#pragma argsused</font></tt> 

<br><tt>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 

lpCmdLine, <b>int</b> nCmdShow)</tt> 

<br><tt>\{</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayDim3 dim(100, 10, 20);</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayLong3 array(dim);</tt> 

<br><tt>&nbsp;&nbsp; <b>for</b>(<b>int</b> i = 0; i &lt; 100; i++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> j = 0; j &lt; 

10; j++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> 

k = 0; k &lt; 20; k++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

array&#91;i&#93;&#91;j&#93;&#91;k&#93; = 5;</tt> 

<p><tt>&nbsp;&nbsp; <b>return</b> 0;</tt> 

<br><tt>\}</tt> 

<br><tt>//---------------------------------------------------------------------------</tt> 

<p><font size=+2>Automatic Destruction of SafeArrays</font> 

<br>Another benefit to using a statically instantiated object to manage 

SafeArrays is for automatic destruction of the internal SAFEARRAY when 

the object goes out of scope. For example, the following code instantiates 

a SafeArray in a <b>try</b>...<b>catch</b> and a SafeArray in a function 

called within the <b>try</b>...<b>catch</b> block. Both SafeArrays are 

automatically destroyed when they go out of scope, whether or not an exception 

occurs. This example also demonstrates passing TSafeArrayT objects by reference 

and by value and manipulating the data contained in the array. 

<p><tt>//---------------------------------------------------------------------------</tt> 

<p><tt><font color="#009900">#include &lt;vcl.h></font></tt> 

<br><tt><font color="#009900">#include &lt;windows.h></font></tt> 

<br><tt><font color="#009900">#include &lt;safearry.h></font></tt> 

<br><tt><font color="#009900">#pragma hdrstop</font></tt> 

<p><tt>//---------------------------------------------------------------------------</tt> 

<br><tt>TSafeArrayBSTR1 CreateBSTRArray(TSafeArrayT&lt;wchar_t, VT_I2, 

2>&amp; SafeArray) \{</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayDim1 Dim(SafeArray.BoundsLength&#91;0&#93;);</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayBSTR1 BSTRArray(Dim);</tt> 

<p><tt>&nbsp;&nbsp; WideString wstr;</tt> 

<br><tt>&nbsp;&nbsp; <b>for</b>(<b>int</b> i = 0; i &lt; SafeArray.BoundsLength&#91;0&#93;; 

i++) \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wstr.Empty();</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> j = 0; j &lt; 

SafeArray.BoundsLength&#91;1&#93;; j++) \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wstr.Insert(WideString(SafeArray&#91;j&#93;&#91;i&#93;), 

wstr.Length()+1);</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \}</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BSTRArray&#91;i&#93; = wstr.Detach();</tt> 

<br><tt>&nbsp;&nbsp; \}</tt> 

<p><tt>&nbsp;&nbsp; <b>return</b> BSTRArray;</tt> 

<br><tt>\}</tt> 

<p><tt><font color="#009900">#pragma argsused</font></tt> 

<br><tt>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 

lpCmdLine, <b>int</b> nCmdShow)</tt> 

<br><tt>\{</tt> 

<br><tt>&nbsp;&nbsp; <b>try</b> \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Fill a 10x10 array of chars with 

where each row consists of</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // chars '0', '1', '2',...,'9'</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSafeArrayDim2 Dim(10, 10);</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSafeArrayT&lt;<b>wchar_t</b>, VT_I2, 

2> Array(Dim);</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>char</b> temp&#91;2&#93;;</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> i = 0; i &lt; 

10; i++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> 

j = 0; j &lt; 10; j++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

Array&#91;j&#93;&#91;i&#93; = WideChar((itoa(j, temp, 10))&#91;0&#93;);</tt> 

<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create an array of 10 BSTRS, where 

each BSTR consists</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // of the string, "0123456789". 

Each row in the 10x10 array</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // of chars is converted to the 

equivalent BSTR.</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSafeArrayBSTR1 BSTRArray = CreateBSTRArray(Array);</tt> 

<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Display the BSTRs.</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WideString msg;</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>for</b>(<b>int</b> i = 0; i &lt; 

10; i++)</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg = msg + WideString(BSTRArray&#91;i&#93;) 

+ WideString("n");</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShowMessage(msg);</tt> 

<br><tt>&nbsp;&nbsp; \} <b>catch</b>(Exception&amp; E) \{</tt> 

<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShowMessage(E.Message);</tt> 

<br><tt>&nbsp;&nbsp; \}</tt> 

<p><tt><b>return</b> 0;</tt> 

<br><tt>\}</tt> 

<br><tt>//---------------------------------------------------------------------------</tt> 

<p>This program demonstrates the numerous ways TSafeArrayT can be used 

to create, modify, and convert data, while letting the exception handling 

mechanism automatically clean up resources if an error occurs. 

<p><font size=+2>SAFEARRAY Ownership</font> 

<br>Care must be taken when accessing the SAFEARRAY structure stored by 

a TSafeArrayT directly in order to avoid the destruction of the SAFEARRAY 

in more than one place or not at all. Often, when using straight Win32 

functions or those of another API that work directly with the SAFEARRAY 

structure, you still want to use TSafeArrayT to manage the data. The following 

code demonstrates three cases: one, a newly created SAFEARRAY is returned 

from a function; two, a newly created SAFEARRAY is returned in an out parameter; 

three, where a preexisting SAFEARRAY is to be passed to a function. 

<p><tt><font color="#009900">#include &lt;vcl.h></font></tt> 

<br><tt><font color="#009900">#include &lt;windows.h></font></tt> 

<br><tt><font color="#009900">#include &lt;safearry.h></font></tt> 

<br><tt><font color="#009900">#pragma hdrstop</font></tt> 

<p><tt>//---------------------------------------------------------------------------</tt> 

<p><tt><font color="#009900">#pragma argsused</font></tt> 

<br><tt>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 

lpCmdLine, <b>int</b> nCmdShow)</tt> 

<br><tt>\{</tt> 

<br><tt>&nbsp;&nbsp; SAFEARRAYBOUND sabdBounds&#91;2&#93; = \{ \{10, 0\}, \{20, 0\} 

\};</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayLong2 Array1(SafeArrayCreate(VT_I4, 2, sabdBounds));</tt> 

<p><tt>&nbsp;&nbsp; TSafeArrayLong2 Array2;</tt> 

<br><tt>&nbsp;&nbsp; SAFEARRAY* sa = Array1.Detach();</tt> 

<br><tt>&nbsp;&nbsp; SafeArrayCopy(sa, &amp;Array2);</tt> 

<br><tt>&nbsp;&nbsp; SafeArrayDestroy(sa);</tt> 

<p><tt>&nbsp;&nbsp; <b>return</b> 0;</tt> 

<br><tt>\}</tt> 

<br><tt>//---------------------------------------------------------------------------</tt> 

<p>The first two lines of WinMain initiliaze <i>Array1</i> with the return 

value of <i>SafeArrayCreate</i>. At this point, ownership of the SAFEARRAY 

is in the hands of Array1. The only method provided to access the internal 

SAFEARRAY is by detaching it with <i>TSafeArrayT::Detach()</i>. Once this 

method is called, the SAFEARRAY is no longer associated with Array1 and 

must be destroyed explicitly, as demonstrated the example. Not doing so 

will cause a resource leak. <i>Array2</i> is constructed with no data or 

dimension sizes. Its internal SAFEARRAY is accessed and initialized by 

the Win32 <i>SafeArrayCopy</i> function. The &amp; operator was overloaded 

for initializing TSafeArrayT objects by using them as an out parameter. 

This will only work if the TSafeArrayT object has not yet been initialized. 

If it has already, an exception is thrown. SAFEARRAY objects can be detached 

and reattached to TSafeArrayT objects as many times as desired. However, 

attempting to attach a SAFEARRAY that does not match the type and dimensions 

of the TSafeArrayT object will result in an exception. 

<p><tt><font color="#009900">#include &lt;vcl.h></font></tt> 

<br><tt><font color="#009900">#include &lt;windows.h></font></tt> 

<br><tt><font color="#009900">#include &lt;safearry.h></font></tt> 

<br><tt><font color="#009900">#pragma hdrstop</font></tt> 

<p><tt>//---------------------------------------------------------------------------</tt> 

<p><tt><font color="#009900">#pragma argsused</font></tt> 

<br><tt>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 

lpCmdLine, <b>int</b> nCmdShow)</tt> 

<br><tt>\{</tt> 

<br><tt>&nbsp;&nbsp; SAFEARRAYBOUND sabdBounds&#91;2&#93; = \{ \{10, 0\}, \{20, 0\} 

\};</tt> 

<br><tt>&nbsp;&nbsp; TSafeArrayLong2 Array1(SafeArrayCreate(VT_I4, 2, sabdBounds));</tt> 

<p><tt>&nbsp;&nbsp; TSafeArrayLong2 Array2;</tt> 

<br><tt>&nbsp;&nbsp; SAFEARRAY* sa = Array1.Detach();</tt> 

<br><tt>&nbsp;&nbsp; SafeArrayCopy(sa, &amp;Array2);</tt> 

<br><tt>&nbsp;&nbsp; Array1.Attach(sa);</tt> 

<p><tt>&nbsp;&nbsp; <b>return</b> 0;</tt> 

<br><tt>\}</tt> 

<br><tt>//---------------------------------------------------------------------------</tt> 

<p>This last example is identical to the one before, except that, instead 

of explicitly destroying the SAFEARRAY <i>sa</i>, it is reattached to Array1 

which destroys it when Array1 goes out of scope. 

  </table> 

</BODY> 

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -