Retrieving a HOOPS Exchange array item in C# using ExchangeSharp

ExchangeSharp provides a direct means to access HOOPS Exchange from C# without needing to resort to C++/CLI (Exchange Sharp Project | Tech Soft 3D Innovation Lab).

When working with Exchange arrays, you’ll find occasion where you need to pull out a given item from the array. The example given in the intro video to ExchangeSharp was for an array of pointers which is common when traversing the PRC tree (arrays of product occurences, arrays of representation items, etc). That is achieved using the below.

var childRepresentationItemPtr = Marshal.ReadIntPtr(repItemSet.m_ppRepItems, riIdx * Marshal.SizeOf(typeof(IntPtr)));

This code is specific to an array of pointers. So what if you want to access a non-pointer item in an array? The below will do that for you in a generic manner.

/// <summary>
/// given an unmanaged pointer to an array of values, return the value at the specified index
/// </summary>
public static T GetItemFromPointerToArray<T>(IntPtr mem1, int idx)
{
    if (mem1 == IntPtr.Zero)
        return default(T);

    // copy the desired value from the source unmanaged array into a local array
    byte[] ba = new byte[Marshal.SizeOf<T>()];
    for (int i = (idx * Marshal.SizeOf<T>()), j = 0; j < ba.Length; i++, j++)
        ba[j] = Marshal.ReadByte(mem1, i);

    // prepare result value
    var result = new T[1];
    var resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);
    var resultPtr = resultHandle.AddrOfPinnedObject();

    // copy into the result value
    Marshal.Copy(ba, 0, resultPtr, Marshal.SizeOf<T>());

    // cleanup
    resultHandle.Free();

    return result[0];
}

It was a bit tricky to get this to work with a generic type, so I thought I’d post it here in case others find it useful.

Some examples of using this involve pulling out PMI markup tessellation data. See below.

using var tessMarkupData = new A3DTessMarkupWrapper(pTess);
...
var codesArr0 = ExchangeHelpers.GetItemFromPointerToArray<uint>(tessMarkupData.m_puiCodes, (int)(codeIdx + 0));
...
matrixValues[i] = ExchangeHelpers.GetItemFromPointerToArray<double>(tessBaseData.m_pdCoords, i);
1 Like