函数从MATLAB中正确工作,但不是从.net调用时

本文关键字:net 调用 工作 MATLAB 函数 | 更新日期: 2023-09-27 18:09:25

我使用MATLAB Builder NE进行互操作性,从c# . net程序中调用MATLAB函数,该程序是作为开源应用程序ClearCanvas的插件构建的。当我从。net程序正常运行代码时,我通常(但并非总是)得到错误消息

MWMCR::EvaluateFunction error…引用单元格数组中不存在的元素。错误=> ComputeT1Maps。M在第178行

问题中的MATLAB代码行如下:

seriesHeader = currentSlab.Slice{1}.MetaData{1}.Header;

Header是由MATLAB的dicominfo函数给出的形式的结构体,MetaData{n}是包含第n个图像文件的文件名和图像头结构体的结构体。

ComputeT1Maps函数的函数签名是:

function ComputeT1Maps(data, options)

为了找出这个错误,我在ComputeT1Maps函数的开头放入以下行,以保持状态,以便我可以看到从。net传递给MATLAB的值:

save(fullfile('F:'MATLAB'T1Mapping', 'T1_debug.mat'), 'data', 'options', ...
    '-mat', '-v7.3');

因此,保留了这个函数的输入(从调用它的。net程序接收),然后我尝试在加载保存的变量后从交互式MATLAB会话运行我的ComputeT1Maps函数,以便我可以利用MATLAB的调试工具来找出为什么我得到错误。就在那时,事情变得非常奇怪。当给出与从我的。net程序调用时给出的完全相同的操作数时,该函数从交互式MATLAB会话中工作得很好。这怎么可能呢?当从c# .NET调用该函数时如何失败,但在交互式MATLAB会话中给定完全相同的输入时如何正常运行?此外,同样的代码以前用于工作,错误只有在我将MATLAB和MCR的本地安装更新到最新版本(2011b)后才开始发生。

在。net端,传递给MATLAB的data由以下函数构造:
    public void ExchangeData(MultidimensionalDataCollection mdc, string outputPath, bool generateAncillaryTestImages, 
        bool excludeAcquisitions, double[] exclusionList, bool showProgressBar, bool displayComputedImages, 
        bool pauseAtEachSlice, bool softwareDiagnostics, bool displayProgressBar)
    {
        try
        {
            int subspaceIndex = 0;
            int slabIndex = 0;
            int sliceIndex = 0;
            int imageIndex = 0;
            MWStructArray topLevelGrouping;
            MWCellArray geometricSubspaceList;
            MWStructArray geometricGrouping;
            MWCellArray slabList;
            MWStructArray slabGrouping;
            MWCellArray sliceList;
            MWStructArray sliceGrouping;
            MWCellArray imageMetaData;
            MWStructArray perImageData;
            MWArray[] result;
            MWLogicalArray successFlag;
            MWStructArray header;
            MWCellArray sopInstanceUids;
            MWStructArray t1MapOptions;
            topLevelGrouping = new MWStructArray(1, 1, new string[] { "GeometricSubspace", 
                "GeometricSubspaceCount" });
            topLevelGrouping["GeometricSubspaceCount", 1] = mdc.Count;
            geometricSubspaceList = new MWCellArray(1, mdc.Count);
            subspaceIndex = 0;
            foreach (GeometricSubspace subspace in mdc)
            {
                subspaceIndex++;
                geometricGrouping = new MWStructArray(1, 1, new string[] { "Slab", 
                    "SlabCount" });
                geometricGrouping["SlabCount", 1] = subspace.Count;
                slabList = new MWCellArray(1, subspace.Count);
                slabIndex = 0;
                foreach (Slab slab in subspace)
                {
                    slabIndex++;
                    slabGrouping = new MWStructArray(1, 1, new string[] { "Slice", 
                        "SliceCount" });
                    slabGrouping["SliceCount", 1] = slab.Count;
                    sliceList = new MWCellArray(1, slab.Count);
                    sliceIndex = 0;
                    foreach (Slice slice in slab)
                    {
                        sliceIndex++;
                        sliceGrouping = new MWStructArray(1, 1, new string[] { 
                            "ImageCount", "MetaData", "MultidimensionalPixelData",
                            "SliceLocation", "SopInstanceUids" });
                        sliceGrouping["ImageCount", 1] = slice.Count;
                        imageMetaData = new MWCellArray(1, slice.Count);
                        int rows, columns;
                        short[,,,] multidimensionalPixelData = null;
                        imageIndex = 0;
                        foreach (Image image in slice)
                        {
                            imageIndex++;
                            short[,] imageMatrix = null;
                            if (!image.ImageSopClass.DicomUid.Equals(DicomUids.MRImageStorage))
                                throw new NotSupportedException("SopClass " + image.ImageSopClass.Name + " is not supported.");
                            else
                            {
                                DicomUncompressedPixelData rawPixelData = image.PixelData;
                                imageMatrix = GetCCImageMatrix(rawPixelData, out rows, out columns);
                                if (imageIndex == 1)
                                {
                                    multidimensionalPixelData = new short[slice.Count, 1, columns, rows];
                                }
                                for (int i = 0; i < rows; i++)
                                {
                                    for (int j = 0; j < columns; j++)
                                    {
                                        // Remember that C# array indices start with 0 while in MATLAB they start with 1
                                        multidimensionalPixelData[imageIndex - 1, 0, i, j] = imageMatrix[i, j];
                                    }
                                }
                            }
                            perImageData = new MWStructArray(1, 1, new string[] { "FileName", "Header" });
                            perImageData["FileName", 1] = image.FileName;
                            result = _mlT1Mapping.QT1GetDicomHeader(2, image.FileName);
                            if (result == null)
                                throw new Exception("GetDicomHeader failed to read the header file for filename:  " +
                                    image.FileName);
                            else
                            {
                                // MWStructArray
                                successFlag = (MWLogicalArray)result[0];
                                bool[] headerObtained = successFlag.ToVector();
                                if (headerObtained[0])
                                {
                                    header = (MWStructArray)result[1];
                                    perImageData["Header", 1] = header;
                                    imageMetaData[1, imageIndex] = perImageData;
                                }
                                else
                                {
                                    Console.WriteLine("GetDicomHeader failed to read the header file for filename:  " +
                                        image.FileName);
                                }
                            }
                        }
                        sliceList[1, sliceIndex] = sliceGrouping;
                        sliceGrouping["MetaData", 1] = imageMetaData;
                        sliceGrouping["SliceLocation", 1] = slice.SliceLocation;
                        List<string> theSops = slice._sopList;
                        sopInstanceUids = new MWCellArray(1, slice._sopList.Count);
                        int count = 0;
                        foreach (string sop in theSops)
                        {
                            count++;
                            sopInstanceUids[1, count] = sop;
                        }
                        sliceGrouping["SopInstanceUids", 1] = sopInstanceUids;
                        sliceGrouping["MultidimensionalPixelData", 1] = (MWNumericArray)multidimensionalPixelData;
                    }
                    slabList[1, slabIndex] = slabGrouping;
                    slabGrouping["Slice", 1] = sliceList;
                }
                geometricSubspaceList[1, subspaceIndex] = geometricGrouping;
                geometricGrouping["Slab", 1] = slabList;
            }
            topLevelGrouping["GeometricSubspace", 1] = geometricSubspaceList;
            t1MapOptions = new MWStructArray(1, 1, new string[] { "DirectoryPath",
                "ComputeDifferenceImages", "ComputeMultiplicationImages", "DisplayComputedImages", "PauseAtEachSlice",
                "SoftwareDiagnostics", "DisplayProgressBar"
            });
            t1MapOptions["DirectoryPath"] = (MWCharArray)outputPath;
            t1MapOptions["SaveS0Maps"] = (MWLogicalArray)generateAncillaryTestImages;
            t1MapOptions["ExcludeAcquisitions"] = (MWLogicalArray)excludeAcquisitions;
            t1MapOptions["ExclusionList"] = (MWNumericArray)exclusionList;
            t1MapOptions["DisplayComputedImages"] = (MWLogicalArray)displayComputedImages;
            t1MapOptions["PauseAtEachSlice"] = (MWLogicalArray)pauseAtEachSlice;
            t1MapOptions["SoftwareDiagnostics"] = (MWLogicalArray)softwareDiagnostics;
            t1MapOptions["DisplayProgressBar"] = (MWLogicalArray)displayProgressBar;
            _mlT1Mapping.ComputeT1Maps(topLevelGrouping, t1MapOptions);
        }
        catch (Exception)
        {
            throw;
        }
    }

函数从MATLAB中正确工作,但不是从.net调用时

我还不能100%确定我已经修复了一切,但到目前为止,经过一些更改后,测试似乎是成功的。似乎问题的关键在于一些赋值的顺序被调换了。这种情况在一些地方发生过。例如,而不是:

sliceList[1, sliceIndex] = sliceGrouping;
sliceGrouping["MetaData", 1] = imageMetaData;

应该按以下顺序排列:

sliceGrouping["MetaData", 1] = imageMetaData;
sliceList[1, sliceIndex] = sliceGrouping;

关于这个错误的奇怪的事情是,代码在以前版本的MATLAB中工作得很好。它根本就不应该起作用!