IronPython: How to call a function that expects an array of value-types?
Question: I have come across a problem with IronPython that I can't solve. I need to
call a function that takes a parameter of type array to value-type. The
function-signature (in C++/CLI notation) is this:

    
    
    static int PLGServiceInterface::PLGService::MapLowSpeedRealtimeNames(cli::array<System::String ^> ^ SignalNames, int timeout_ms, cli::array<PLGServiceInterface::LVCluster_1> ^% Channels, System::String ^% ReportText)
    

When I call the function from IronPython

    
    
    import clr
    clr.AddReferenceToFileAndPath('PLGServiceAPI.dll')
    
    from System import String, Array
    from PLGServiceInterface import PLGService, LVCluster_1
    
    outtext = clr.Reference[String]()
    outdata = clr.Reference[Array[LVCluster_1]]()
    PLGService.MapLowSpeedRealtimeNames(('hello', 'world'), 300, outdata, outtext)
    

I get the following error

    
    
    Traceback (most recent call last):
      File "test2.py", line 9, in <module>
    TypeError: expected StrongBox[Array[LVCluster_1]], got StrongBox[Array[LVCluster_1]]
    

The error message is not very helpful but I assume the problem is that
"outdata" is an array containing value types instead of reference types.
Apparently IronPython doesn't know how to do the boxing in that case.

With C++/CLI I can use the function just fine:

    
    
    using namespace System;
    using PLGServiceInterface::LVCluster_1;
    using PLGServiceInterface::PLGService;
    
    int main(array<System::String ^> ^args)
    {
        array<LVCluster_1> ^outdata;
        array<String^> ^names = gcnew array<String^>{"one", "two"};
        String ^o;
    
        PLGService::MapLowSpeedRealtimeNames(names, 300, outdata, o);
    
        Console::WriteLine(o);
    
        Console::Read();
    
        return 0;
    }
    

I assume if the function would instead expect an array of references

    
    
    array<LVCluster_1 ^> ^outdata
    

I could call it with IronPython.

Is there any way to make this work with IronPython? By the way, the assembly
was created with LabView and LVCluster_1 is a LabView-Cluster (structure).

Edit: The Intermediate Language signature of MapLowSpeedRealtimeNames is this:

    
    
    .method public hidebysig static int32  MapLowSpeedRealtimeNames(string[...] SignalNames,
                                                                    int32 timeout_ms,
                                                                    [out] valuetype PLGServiceInterface.LVCluster_1[...]& Channels,
                                                                    [out] string& ReportText) cil managed
    

Does anybody know what the meaning of the 3 dots in the array brackets is?
When I compile a function that takes an array in C++/CLI, I only get the
opening and closing brackets without the dots in between.

These dots seem suspicious to me because I also get the TypeError when calling
a method that takes an out-parameter of type array of double(float64):

    
    
    .method public hidebysig static int32  ReadVariables(string[...] SignalNames,
                                                         int32 timeout_ms,
                                                         [out] string& ReportText,
                                                         [out] float64[...]& Data) cil managed
    

Generates the error

    
    
    TypeError: expected StrongBox[Array[float]], got StrongBox[Array[float]]
    


Answer: Have you tried using Array.CreateInstance(LVCluster_1, length) to create the
array? See example below:

    
    
    outdata = Array.CreateInstance(LVCluster_1, 2)
    

The code above works for me, but my c++/cli function signature don't use the
tracking reference (%). So if I were to re-write your function signature it
would look like:

    
    
    static int PLGServiceInterface::PLGService::MapLowSpeedRealtimeNames(cli::array<System::String ^> ^ SignalNames, int timeout_ms, cli::array<PLGServiceInterface::LVCluster_1> ^ Channels, System::String ^ ReportText)
    

