Search code examples
visual-studiocomidlmidl

SAFEARRAY type not known when compiling using MIDL


My ODL file looks like this:

import "oaidl.idl";
import "ocidl.idl";

[oleautomation, uuid(/* redacted */)]
interface ISomething : IUnknown
{
    HRESULT DoSomething(
        [in]BSTR User,
        [in]VARIANT Object,
        [in]SAFEARRAY Array         // may be NULL
        );
}

I'm getting errors:

1>.\Something.odl(17): error MIDL2139: type of the parameter cannot derive from void or void * : [ Type 'PVOID' ( Parameter 'Array' ) ] 1>.\Something.odl(17): error MIDL2105: pointee / array does not derive any size : [ Field 'rgsabound' of Struct 'tagSAFEARRAY' ( Parameter 'Array' ) ] 1>.\Something.odl(17): error MIDL2465: Structures containing conformant arrays must be passed by reference. See MSDN for more details : [ Struct 'tagSAFEARRAY' ( Parameter 'Array' ) ]

If I change the type from SAFEARRAY to SAFEARRAY* (which I don't believe to be correct?) I get different errors:

1>.\Something.odl(17): error MIDL2139: type of the parameter cannot derive from void or void * : [ Type 'PVOID' ( Parameter 'Array' ) ] 1>.\Something.odl(17): error MIDL2105: pointee / array does not derive any size : [ Field 'rgsabound' of Struct 'tagSAFEARRAY' ( Parameter 'Array' ) ]

Is this simply a case that I need to include some other headers? I'm compiling using the MIDL compiler in VS2013, aparently the command-line looks like this:

/iid "./source/Something_i.c" /h "Something.h" /W1 /char signed /notlb /app_config /nologo /dlldata "./source/Something_dlldata.c" /proxy "./source/Something_p.c" 

Solution

  • You need to tell it what type of elements are in your SafeArray. For example SAFEARRAY(unsigned char) *Data for an array of unsigned chars. If the data type of the array elements is variable at runtime you could pass the elements as a SafeArray of VARIANT. For example:

    import "oaidl.idl";
    import "ocidl.idl";
    
    [oleautomation, uuid(/* redacted */)]
    interface ISomething : IUnknown
    {
        HRESULT DoSomething(
            [in]BSTR User,
            [in]VARIANT Object,
            [in]SAFEARRAY(unsigned char) *Array         // may be NULL
            );
    }