Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7036273
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T01:24:16+00:00 2026-05-28T01:24:16+00:00

My question is extremely specific to the arcanes of the matlab compiler and runtime.

  • 0

My question is extremely specific to the arcanes of the matlab compiler and runtime. As only people familiar with matlab runtime API may answer, I shortened much details. Please let me know if I should be more verbose.

Introduction

Using the matlab compiler & runtime I can call a function written in m-code from a C# program. Let’s say calling:

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

with (somewhere behind some dllimports in the C# code):

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

So far, so good, I have no issue with this (i.e intializing the runtime, loading the ‘.cft’ file, marshalling back and forth MxArray with .Net types, etc…)

My Problem

I would like to survey the progression of my foo function using some cancel and progress callbacks:

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
%]

But of course I would like these callbacks to be in the C# code, not within the m-one.

Investigations

  1. Looking at ‘mclmcr.h’ header file, it looks like these functions may be of help:

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

    Unfortunatly these are fully undocumented and I found no use case I could mimic to understand how they work.

  2. I’ve also thought about creating a COM visible object in C# and pass it as a parameter to the matlab code:

    // 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
    %]
    

    I’m very familiar with functions to create numeric and structure arrays and know how to use them:

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

    Anyhow, how COM objects are packaged to MxArrays, I don’t know?

Further investigations

Day+1

Even if still unstable, I succeeded to have matlab to callback into my C# code and it seems that mclCreateSimpleFunctionHandle is the direction to go.

Note: Below code is for reference only. It may not be suitable in your own context as is. I’ll provide simpler code later on (i.e. once I’ll get stable solution).

  1. Looking to the signature of the mxFunctionPtr, I created two delegates like this:

    // 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. I also linked to the runtime like this:

    [DllImport("mclmcrrt74.dll", EntryPoint = "mclCreateSimpleFunctionHandle", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
    static extern IntPtr _mclCreateSimpleFunctionHandle(MCRInteropDelegate fctn);
    
  3. Assuming MxArray is a .NET class of mine that simply encapsulate for mxArray* handles, I then marshaled my delegates like this:

    // 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. Finally, assuming module is an instance of MCRModule (again, a class of mine to encapsulate hInst* in low level mclFeval API), I was able to call foo function and have it to enter my .NET cancel delegate like this:

    // 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);
    

    This .NET code worked fine, and foo really made callback to the cancel delegate properly.

    Only problem, is that it is quite unstable. My guess is that I used too many anonymous functions, and probably some of them are disposed too early …

    Will try to provide with stable solution within the next few days (hopefully with simpler code to read and copy-paste in your own context for immediate testing).

    Please let me know if you think I’m going the wrong direction with mclCreateSimpleFunctionHandle.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T01:24:17+00:00Added an answer on May 28, 2026 at 1:24 am

    Got it

    mclCreateSimpleFunctionHandle was effectively the right API function to call at in order to create an array variable (on matlab’s side) holding for a function pointer (on external’s side). I’m now able to have compiled m-code to call back into my C# code for cancellation and progression purposes.

    Correct marshalling for mclCreateSimpleFunctionHandle is described here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This may be an extremely easy question but I can't get my head around
Forgive me if there is an extremely simple answer to this question. I am
The question is probably extremely easy to resolve, but I need to resolve it
Sorry about the extremely vague question title (any suggestions for improvements welcome) I have
Forgive me, I'm new to Java and have an extremely basic question. I have
My problem is extremely similar to the one described in this SO question ,
This is my first question, but I've already found this site extremely helpful, so
Ok, let me preface this question with the fact that I am extremely new
My question is very similar to this question but a bit more specific. My
(Sorry if this is a really long question, it said to be specific) The

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.