IronPython:如何调用需要一组值类型的函数?

时间:2015-03-27 16:07:23

标签: arrays ironpython il boxing

我遇到过IronPython的问题,我无法解决。我需要调用一个函数,它将类型数组的参数赋值为value-type。函数签名(用C ++ / CLI表示法)是这样的:

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

当我从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)

我收到以下错误

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

错误消息不是很有帮助,但我认为问题是“outdata”是一个包含值类型而不是引用类型的数组。显然IronPython在那种情况下不知道怎么做拳击。

使用C ++ / CLI我可以正常使用该函数:

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;
}

我假设函数会改为期望引用数组

array<LVCluster_1 ^> ^outdata

我可以用IronPython调用它。

有没有办法让IronPython工作?顺便说一下,程序集是使用LabView创建的,LVCluster_1是LabView-Cluster(结构)。

编辑: MapLowSpeedRealtimeNames的中间语言签名是:

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

有人知道数组括号中3个点的含义是什么吗?当我编译一个在C ++ / CLI中使用数组的函数时,我只得到开始和结束括号,而没有两者之间的点。

这些点对我来说似乎很可疑,因为我在调用时也得到了TypeError 采用double类型数组的out-parameter的方法(float64):

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

生成错误

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

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用Array.CreateInstance(LVCluster_1,length)来创建数组?见下面的例子:

outdata = Array.CreateInstance(LVCluster_1, 2)

上面的代码对我有用,但我的c ++ / cli函数签名不使用跟踪引用(%)。因此,如果我要重新编写您的函数签名,它将如下所示:

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