Files
jlibcom/unittest/com/jacob/test/safearray/SafeArrayReleaseTest.java

117 lines
3.4 KiB
Java

package com.jacob.test.safearray;
import com.jacob.com.ComThread;
import com.jacob.com.SafeArray;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
* <p>
* SF 1085370
In my understatnding, an instance of SafeArray java
class has a
value of a pointer to VARIANT structure that contains a
pointer to
a SAFEARRAY strucuture.
On the other hand, we can create a Variant object from
the
SafeArray object like this:
SafeArray sa = ...;
Variant val = new Variant(sa);
the val object has a pointer to another VARIANT
structure that
contains a pointer to the same SAFEARRAY structure.
In this case, the val object has a pointer to another
VARIANT that
contains a pointer to the same SAFEARRAY like this:
+-----------+
|SafeArray | +------------+
| m_pV--->VARIANT(a) |
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +^--------+
|
+-----------+ |
|Variant | +------------+ |
| m_pVariant--->VARIANT(b) | |
+-----------+ | VT_ARRAY| |
| parray-----+
+------------+
When previous objects are rereased by
ComThread.Release(),
first the VARIANT(a) is released by VariantClear()
function,
and second the VARIANT(b) is released by VariantClear()
function too.
But the SAFEARRAY was already released by the
VARIANT(a).
So, in my enviroment (WinXP + J2SDK 1.4.1) the
following java program
is sometimes crash with EXCEPTION_ACCESS_VIOLATION.
To solve this problem, it is nessesary to copy the
SAFEARRAY like this:
+-----------+
|Variant | +------------+
| m_pVariant--->VARIANT(a) |
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +|--------+
|
+-----------+ | copySA()
|SafeArray | +------------+ |
| m_pV--->VARIANT(b) | V
+-----------+ | VT_ARRAY| +---------+
| parray---->SAFEARRAY|
+------------+ +---------+
*
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
public class SafeArrayReleaseTest extends BaseTestCase {
final static int MAX = 300;
public void testSaveArrayRelease() {
int count;
System.out.println("Starting test for max = "+MAX);
for(count = 1; count<MAX; count++)
{
int i = 0;
try
{
ComThread.InitMTA();
for (i = 0; i < count; i++)
{
SafeArray a1 = new SafeArray(Variant.VariantVariant, 2);
a1.setVariant(0, new Variant("foo"));
a1.setVariant(1, new Variant("bar"));
Variant v = new Variant(a1);
SafeArray a2 = v.toSafeArray(true);
if (a2 == null){
System.out.println("got null back from toSafeArray()");
}
}
ComThread.Release();
System.gc();
//System.out.print(".");
}
catch (Exception e)
{
fail("Test fails with i = " + i + " (max = "+MAX+")");
}
}
System.gc();
System.out.println("\nTest ends with count = " + count + " (max = "+MAX+")");
}
}