.NET Access violation when accessing COM object

Viewed 40

I've read all I could find about this topics, but I'm still not sure about the best way to handle this problem.

In our .NET Standard 2.0 library we are importing some C++ dlls using DllImport attribute.

[DllImport("someCPlusPlusLib.dll", CharSet = CharSet.Unicode)]
public static extern void GetXmpArray(byte[] someArray, int someInt, out IntPtr someIntPtr, out int someInt, string someString);

Then we are calling this method in a foreach loop and it would be really good if we could somehow handle the one execution of GetXmpArray that is causing us issue. We know that most of them will run with out any problems.

foreach (var var in someCollection)
{
    //only one run will cause an exception. Others will be successful
    GetXmpArray(someArray, someInt, out someIntPtr, out someInt, someString)
}

Of course using standard try/catch is not working in this case so I've tried running this code in a separate thread but that didn't work as well. The exception is still not being caught.

try
{
    Thread thread = new Thread(
        () =>
        {
            GetXmpArray(someArray, someInt, out someIntPtr, out someInt, someString);
        });
    thread.Start();
    thread.Join();
}
catch
{
    // THIS DOES NOT CATCH THE EXCEPTION
}

I've also tried adding [HandleProcessCorruptedStateExceptions] attribute to the method but from what I've read it won't work with .NET Core and I'm assuming .NET Standard.

We do have access to the underlying c++ code and the authors. They could probably fix the specific issue we are hitting, but I'm wondering if some general error handling solution can be provided here or in C++ code so that if there is some other underlying problem in the future we can handle it gracefully and not crash the entire application.

Edit: Here is a c++ method definition:

BOOL GetXmpArray(byte *someArray, int someInt, byte *&someIntPtr, int &someInt, WCHAR *someString);

and body

BOOL GetXmpArray(byte *someArray, int someInt, byte *&someIntPtr, int &someInt, WCHAR *someString)
{
    ITEM **mdArray = (ITEM **)mallocZeroInit(sizeof(ITEM *) * 1000);
    someInt = extractAllFields(someArray, someInt, mdArray, someString);
    if (mdArray)
    {
        someIntPtr = (byte *)mdArray;
        return (TRUE);
    }
    return (FALSE);
}

Edit2: Calling method showing what the code is doing:

public IReadOnlyCollection<IXmpItem> ReadXmpItemsFromXmp(Stream streamData, string fileId)
{
    var buffer = new byte[streamData.Length];
    streamData.Read(buffer, 0, buffer.Length);
    _libWrapper.GetXmpArray(buffer, buffer.Length, out IntPtr metadataPointer, out int fieldsCount, fileId);
    var xmpItems = new List<IXmpItem>();

    for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++)
    {
        _libWrapper.GetXmpArrayField(metadataPointer, out IntPtr contentPointer, out int fieldId, out int fieldType, out int dataType, fieldIndex);
        string rawContent = _marshalWrapper.PtrToStringUni(contentPointer);
        xmpItems.Add(_xmpItemBuilder.BuildXmpItem(fieldId, rawContent, (DataType)dataType, (FieldType)fieldType));

        _libWrapper.FreePointer(contentPointer);
    }

    _libWrapper.FreeArray(metadataPointer, fieldsCount);
    return xmpItems;
}
0 Answers
Related