0

I have a COM class (developed in C++, just in case it matters), which has a method "GetStructList" which should return a list of some custom type, and I'm developing a .NET application which should get that list.

I control the COM class code as well as the application, and I am unable to obtain the data.

The COM class code:

1- IDL:

HRESULT GetList([in,out] SAFEARRAY(struct MyStruct)* myStructs);
// I have also tried with [out] instead of [in, out]

[uuid(628913FC-CC26-1654-472F-0B70CC39DEE0)]
struct MyStruct
{
    int myInt;
    DOUBLE myDouble;

};

2- CPP:

STDMETHODIMP MyClass::GetList(SAFEARRAY** myStructs)
{
    SAFEARRAY* psa = *myStructs;
    SAFEARRAYBOUND sab = {someSize, 0};
    MyStruct *pData;
    IRecordInfo *pRI;
    HRESULT hr;

    hr = GetRecordInfoFromGuids(LIBID_MyCOMLib, 1, 0, 0x409, __uuidof(MyStruct), &pRI);
    psa = SafeArrayCreateEx(VT_RECORD, 1, &sab, pRI);
    pRI->Release();
    pRI = NULL;
    hr = SafeArrayAccessData(psa, (void**)&pData);
    for (size_t i = 0; i < someSize; i++) 
    {
        pData[i].myInt = someInt;
        pData[i].myDouble = somedouble;
    }
    hr = SafeArrayUnaccessData(psa);

    return S_OK;
}

.Net Code (VB):

Option Strict
...
<MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_RECORD)>
Private m_List As MyStruct()

Private Sub btnGetList_Click(sender As System.Object, e As System.EventArgs) 
    Dim m_List() As MyStruct
    m_ComObject.GetList(m_List) 

    ' I have tried several other things, getting different errors with each of them'
    'm_ComObject.GetList(CType(m_List, Array))'

    'Dim structs() As MyStruct'
    'Dim arr as System.Array = structs '
    'm_ComObject.GetList(arr)'

    For Each o In cortes
        Dim s As MyStruct = CType(o, MyStruct)
        MsgBox(s.myInt)
        Exit For
    Next
End Sub

How can I achieve this?

0

1 Answer 1

1

What is the generated interop signature?

What exact errors do you get?

The myStruct argument in COM interface should be [out], not [in, out]

Is the part:

Dim m_List() As SceneCutInfo
m_ComObject.GetList(m_List) 

meant to be:

Dim m_List() As MyStruct
m_ComObject.GetList(m_List) 

However, unless you have a really good reason to use SAFEARRAYs (e.g. an Automation compliant interface), I would suggest using normal arrays, as there is no need to fight with VT_RECORD stuff.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you, I tried hard to omit the SAFEARRAY word in the question because I don't have any reason to use SAFEARRAYs, any way to return an array is valid for me. I think SAFEARRAYs have become my standard due to too much code called from VB6. Now, how do I define a normal array for COM interop?
do you get same problems if you use floats instead of doubles?
Yes, "SceneCutInfo" was the original struct name, and I forgot to change it again; I've fixed it now. The error are mostly Null References.
The error persists using floats instead of doubles. The exact code I posted doesn't seem to compile with Option Strict On, so I'm passing CType(m_List, Array) isntead of just m_List.
Hmm, I have finally fixed this. I'm not sure what I was doing wrong but it works now. Now, what should I use instead of SAFEARRAYs? If I use MyStruct*, then I don't know the array length...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.