从.net dll返回结构(C#)

时间:2016-05-08 22:10:25

标签: matlab

我有一个.net DLL(C#),它通过TCP从传感器接收实时(和大量)数据。数据将作为自定义对象的数组出现。 (称之为SensorPacket,它有大约20个字段,主要是float和int)。

我一直通过事件发送到matlab(工作正常)。但Matlab将它们视为.NET对象的数组。我宁愿把它作为一个struct数组发送出去。怎么样?

是的,可以通过以下方法将此数组转换为单元数组:

http://www.mathworks.com/help/matlab/matlab_external/net-arrays-to-cell-arrays.html

但仍然将此作为.net对象的单元格数组。可以投射对象以便我可以获取值吗?

更好的是发送一个struct的数组/数组。

我曾尝试将其转换为JSON,并使用matlab JSON阅读器转换为结构,但这非常慢: http://www.mathworks.com/matlabcentral/fileexchange/33381-jsonlab--a-toolbox-to-encode-decode-json-files

不要笑,但我正在考虑使用DLL编写一个.MAT文件,然后将该句柄发送给Matlab。本作者可能会工作:http://www.mathworks.com/matlabcentral/fileexchange/16319-csmatio--mat-file-i-o-api-for-net-2-0

在下一页中,它说我可以返回一个结构或类,但我的经验是,它返回一个System.Object

http://www.mathworks.com/help/matlab/matlab_external/handling-net-data-in-matlab_bte9owt-1.html

1 个答案:

答案 0 :(得分:0)

嗯,看来,与普通C,mex文件不同,你无法返回matlab本机结构和对象。但是你可以返回你定义的类的C#对象,你可以从Matlab访问这些属性(只需做一个属性(netObj)然后你会看到。真的,你会看到一个System.String []用于字符串,但是可以通过对对象执行char()来修复。大多数其他标量也可以工作。

在我的情况下,我通过SingnalR获取JSON消息,将它们转换为ExpandDo对象,然后创建单个类对象,并将EVENTS发送到matlab。这一切都有效,比Matlab解析JSON快20倍。但对于实际的批量工作来说仍然有点慢。我现在开始使用csmatio工具(https://sourceforge.net/projects/csmatio)来编写.MAT文件,然后我将向Matlab发出数据已准备就绪的信号。

但是下面你可以看到我的C#代码,我现在正在写它:(注意,你可以创建.NET事件)它们将像Matlab事件一样出现在Matlab中,并将值作为参数传递!我执行task.invoke以防止.NET中的线程挂起,而matlab处理数据。

    public delegate void PostPerson(Portal sender, dynamic e);
    public event PostPerson Post;

        private void deliver(dynamic packet)
    {
        var converter = new ExpandoObjectConverter();
        dynamic data = JsonConvert.DeserializeObject<ExpandoObject>(packet.ToString(), converter);
        dynamic mail;
        String channelName = (string)data.Channel;
        switch (channelName)
        {
            case "Oxford":
                mail = new Oxford(data);
                break;
            case "RADAR":
                mail = new Radar(data);
                break;
            case "SVSRear":
                mail = new SVS(data);
                break;
            case "SVSFront":
                mail = new SVS(data);
                break;
            case "IBEO":
                mail = new IBEO(data);
                break;
            case "Fusion":
                mail = new Fusion(data);
                break;
            default:
                postFail(String.Format("Portal: deliver: Unknown Channel: {0}", channelName));
                return;
        }
        trigger(mail);
    }
    private void trigger(dynamic e)
    {
        if (Post != null)
        {
            //Post(this, e);
            Task.Factory.StartNew(() => { Post(this, e); });
        }
    }