Matlab:如何从外部API调查编译后的m代码进度?

2024-01-10

我的问题非常具体于 matlab 编译器和运行时的奥秘。只有熟悉 matlab 运行时 API 的人才能回答,我缩短了很多细节。请让我知道我是否应该更详细。

介绍

使用 matlab 编译器和运行时,我可以从 C# 程序调用用 m 代码编写的函数。假设调用:

function [result] = foo(n)
%[
    result = 0;
    for k = 1:n,
        pause(1.0); % simulate long processing
        result = result + 42;
    end
%]

with(C# 代码中某些 dllimport 后面的某个位置):

mclFeval(IntPtr inst, string name, IntPtr[] plhs, IntPtr[] prhs)

到目前为止,一切顺利,我对此没有任何问题(即初始化运行时、加载“.cft”文件、使用 .Net 类型来回编组 MxArray 等...)

我的问题

我想调查一下我的进展foo函数使用一些cancel and progress回调:

function [result] = foo(n, cancelCB, progressCB)
%[
    if (nargin < 3), progressCB = @(ratio, msg) disp(sprintf('Ratio = %f, Msg = %s', ratio, msg)); end
    if (nargin < 2), cancelCB = @() disp('Checking cancel...'); end

    result = 0;
    for k = 1:n,

        if (~isempty(cancelCB)), 
            cancelCB(); % Up to the callback to raise some error('cancel');
        end;
        if (~isempty(progressCB)),  
           progressCB(k/n, sprintf('Processing (%i/%i)', k, n));
        end

        pause(1.0); % simulate long processing
        result = result + 42;
    end
%]

但我当然希望这些回调位于 C# 代码中,而不是 m-one 中。

调查

  1. 查看“mclmcr.h”头文件,看起来这些函数可能会有所帮助:

    extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn);
    extern bool mclRegisterExternalFunction(HMCRINSTANCE inst, const char* varname, mxFunctionPtr fcn);
    

    不幸的是,这些完全没有记录,我发现没有可以模仿的用例来理解它们是如何工作的。

  2. 我还考虑过在 C# 中创建一个 COM 可见对象并将其作为参数传递给 matlab 代码:

    // Somewhere within C# code:
    var survey = new ComSurvey();
    survey.SetCancelCallback =  () => { if (/**/) throw new OperationCancelException(); };
    survey.SetProgressCallback = (ratio, msg) => { /* do something */ };
    

     

    function [result] = foo(n, survey)
    %[
        if (nargin < 2), survey = []; end
    
        result = 0;
        for k = 1:n,
    
            if (~isempty(survey)),
               survey.CheckCancel(); % up to the COM object to raise exception
               survey.SetProgress(k/n, sprintf('Processing... %i/%i', k, n));
            end
    
            pause(1.0); % simulate long processing
            result = result + 42;
        end
    %]
    

    我非常熟悉创建数字和结构数组的函数并知道如何使用它们:

    extern mxArray *mxCreateNumericArray(...)
    extern mxArray *mxCreateStructArray(...)
    

    无论如何,COM对象是如何包装到MxArrays的,我不知道?

进一步调查

Day+1

即使仍然不稳定,我成功地让 matlab 回调到我的 C# 代码中,看起来mclCreateSimpleFunctionHandle是要走的方向。

注:以下代码仅供参考。它可能不适合您自己的环境。稍后我将提供更简单的代码(即一旦我得到稳定的解决方案)。

  1. 寻找签名mxFunctionPtr,我创建了两个像这样的代表:

    // Mimic low level signature for a Matlab function pointer
    [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    delegate void MCRInteropDelegate(int nlhs, IntPtr[] plhs, int nrhs, IntPtr[] prhs);
    

    and

    // Same signature (but far more elegant from .NET perspective)
    delegate void MCRDelegate(MxArray[] varargouts, MxArray[] varargins);  
    
  2. 我还像这样链接到运行时:

    [DllImport("mclmcrrt74.dll", EntryPoint = "mclCreateSimpleFunctionHandle", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
    static extern IntPtr _mclCreateSimpleFunctionHandle(MCRInteropDelegate fctn);
    
  3. 假设MxArray是我的一个 .NET 类,它简单地封装了mxArray*句柄,然后我像这样整理我的代表:

    // Create MxArray from corresponding .NET delegate
    static MxArray CreateFromDelegate(MCRDelegate del)
    {
        // Package high level delegate signature to a 'dllimport' signature
        MCRInteropDelegate interopDel = (nlhs, plhs, nrhs, prhs) =>
        {
            int k = 0;
    
            var varargouts = new MxArray[nlhs];
            var varargins = new MxArray[nrhs];
    
            // (nrhs, prhs) => MxArray[] varargins 
            Array.ForEach(varargins, x => new MxArray(prhs[k++], false)); // false = is to indicate that MxArray must not be disposed on .NET side
    
            // Call delegate
            del(varargouts, varargins); // Todo: varargouts created by the delegate must be destroyed by matlab, not by .NET !!
    
            // MxArray[] varargouts => (nlhs, plhs)
            k = 0;
            Array.ForEach(plhs, x => varargouts[k++].getPointer());
        };
    
        // Create the 1x1 array of 'function pointer' type
        return new MxArray(MCRInterop.mclCreateSimpleFunctionHandle(interopDel));
    }
    
  4. 最后,假设module是一个实例MCRModule(再次,我的一个类来封装hInst*处于低水平mclFevalAPI),我能够调用foo函数并让它进入我的.NETcancel像这样的委托:

    // Create cancel callback in .NET
    MCRDelegate cancel = (varargouts, varargins) =>
    {
        if ((varargouts != null) && (varargouts.Length != 0) { throw new ArgumentException("'cancel' callback called with too many output arguments"); } 
        if ((varargins != null) && (varargins.Length != 0) { throw new ArgumentException("'cancel' callback called with too many input arguments"); }
    
        if (...mustCancel...) { throw new OperationCanceledException(); }
    }
    
    // Enter the m-code
    // NB: Below function automatically converts its parameters to MxArray
    // and then call low level mclFeval with correct 'mxArray*' handles
    module.Evaluate("foo", (double)10, cancel);
    

    这段 .NET 代码运行良好,并且foo确实回调了cancel正确委派。

    唯一的问题是它相当不稳定。我的猜测是我使用了太多匿名函数,并且可能其中一些函数被过早处理......

    将在接下来的几天内尝试提供稳定的解决方案(希望有更简单的代码可以在您自己的上下文中阅读和复制粘贴以便立即测试)。

    如果您认为我走错了方向,请告诉我mclCreateSimpleFunctionHandle.


Got it

mclCreateSimpleFunctionHandle实际上是调用的正确 API 函数,以便创建一个保存函数指针(在外部一侧)的数组变量(在 matlab 一侧)。我现在可以编译 m 代码来回调我的 C# 代码以实现取消和进展目的。

正确编组mclCreateSimpleFunctionHandle被描述here https://stackoverflow.com/a/8755730/684399

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Matlab:如何从外部API调查编译后的m代码进度? 的相关文章

  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • Matlab的导入函数的范围是什么?

    我正在尝试将一些用 Matlab 编写的代码转换为独立的 编译的 Matlab 应用程序 然而 在出现一些奇怪的错误之后 我意识到代码大量使用了从路径中添加和删除的操作 以避免多次使用多个具有相同名称 但结果 计算不同 的函数这一事实 环顾
  • matlab中无限while嵌套在for循环中

    我想做一个while循环 嵌套在for在 Matlab 中循环以查找数据中不同对之间的距离 我的数据具有以下形式 ID lon lat time 1 33 56 40 89 803 2 32 45 41 03 803 3 35 78 39
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之
  • 如何在 MATLAB 编译的应用程序中运行外部 .m 代码? [复制]

    这个问题在这里已经有答案了 我有一个 MATLAB 项目 我使用 MCC 对其进行编译以获得单个可执行文件 然后我想知道外部程序员是否可以在 exe 中执行他的一些 m 文件 而无需重新编译整个项目 重点是提供一个应用程序 其他开发人员可以
  • 如何在 MATLAB 中将矩阵元素除以列总和?

    有没有一种简单的方法可以将每个矩阵元素除以列和 例如 input 1 4 4 10 output 1 5 4 14 4 5 10 14 以下是执行此操作的不同方法的列表 使用bsxfun https www mathworks com he
  • Deploytool for MATLAB R2013b 不起作用,发生了什么变化?

    多年来我一直在使用集成deploytool为我的同事创建易于分发的 exe 文件 我几天前安装了R2013b 但无法使用deploytool不再了 尝试打包时的日志文件给出了以下内容 ant
  • 保存符号方程以供以后使用?

    From here http www mathworks com help releases R2011a toolbox symbolic brvfu8o 1 html brvfxem 1 我正在尝试求解这样的符号方程组 syms x y
  • 轴标注问题

    通过运行我编写的以下 matlab 函数 可以互换图中的 x 轴和 y 轴 谁能告诉我问题出在哪里或者帮我解决它吗 预先感谢您的任何帮助 function axislabeling n x 1 1 n y 1 1 n z zeros n n
  • 优先连接,Matlab 中的复杂网络

    大家好 我现在正在 MATLAB 中研究优先附件模型 在理解以下内容时遇到一些困难 假设我一开始有 4 个节点 连接如下 time 0 1 lt gt 2 3 lt gt 4 在下一个时间步骤中 我添加一个节点和 4 个连接 然后添加另一个
  • 2D 网格的纹理贴图

    我有一组点 x y meshgrid 1 N 1 M 在常规二维上定义 N x M网格 我还有另一组要点 u v 这是原始网格的一些变形 即 u v f x y 但是我没有实际的f导致变形 如何将纹理映射到由定义的 变形 网格u v 即 给
  • 像matlab一样在python中连接数组而不知道输出数组的大小

    我正在尝试在 python 中连接数组 类似于 matlab array1 zeros 3 500 array2 ones 3 700 array array1 array2 我在 python 中做了以下操作 array1 np zero
  • MATLAB:图像角坐标和引用元胞数组

    我在比较不同元胞数组中的元素时遇到一些问题 这个问题的背景是我正在使用bwboundariesMATLAB 中的函数可追踪图像的轮廓 该图像是结构横截面 我试图找出整个部分是否具有连续性 即 只有一个轮廓由bwboundaries命令 完成
  • 如何在matlab中使矩阵图平滑

    就像上图一样 怎样才能让画面更流畅呢 或者缩小y轴的范围 数据来自二维矩阵 然后我用plot data 请随意提出任何想法 平滑线条的一种方法涉及样本点之间数据的非线性插值 当你这样做时plot x y o http www mathwor
  • 在 MATLAB 中验证输入的最佳实践

    在验证 MATLAB 函数中的输入时 什么时候使用 inputParser 比使用断言更好 或者还有其他更好的工具可用吗 我个人发现使用 inputParser 不必要地复杂 对于 Matlab 始终需要检查 3 项内容 存在 类型和范围
  • 计算向量的导数

    我有以下函数 维维亚尼曲线 Phi t cos t 2 cos t sin t sin t 只需检查它是否有效 s linspace 0 T 1000 plot3 cos s 2 cos s sin s sin s 如何推导函数Phi 可能
  • 用于读取csv写入数组的c++程序;然后操作并打印到文本文件中(已经用 matlab 编写)

    我想知道是否有人可以帮助我 我正在尝试构建一个程序 从 csv 文件中读取大小未知的浮点数大数据块 我已经在 MATLAB 中编写了此代码 但想要编译和分发此代码 因此转向 C 我只是在学习并尝试阅读本文以开始 7 5 19892 4 23
  • 使用 scipy.io 将 python pandas dataframe 转换为 matlab 结构

    我正在尝试使用 scipy io 将 pandas 数据帧保存到 matlab mat 文件 我有以下内容 array1 np array 1 2 3 array2 np array a b c array3 np array 1 01 2
  • Matlab 错误:()-索引必须出现在索引表达式的最后

    我有这段代码 想要在制表符分隔的 txt 文件中写入一个数组 fid fopen oo txt wt for x 1 length s fprintf fid s t n s x 1 end fclose fid 但我收到此错误 Error
  • 可以避免迭代元胞数组时的“s{1} 烦恼”吗?

    The s 1 标题的 烦恼 指的是下面的 for 块中的第一行 for s some cell array s s 1 unpeel the enclosing cell do stuff with s end This s s 1 业务

随机推荐