2011-10-25 4 views
5

मेरा प्रश्न matlab संकलक और रनटाइम के arcanes के लिए बेहद विशिष्ट है। चूंकि केवल मैटलैब रनटाइम एपीआई से परिचित लोग जवाब दे सकते हैं, मैंने बहुत अधिक जानकारी कम कर दी है। अगर मुझे और अधिक वर्बोज़ होना चाहिए तो कृपया मुझे बताएं।Matlab: बाहरी एपीआई से संकलित एम-कोड प्रगति का सर्वेक्षण कैसे करें?

परिचय

का उपयोग matlab संकलक & क्रम मैं एक समारोह के एक सी # कार्यक्रम से एम-कोड में लिखा कॉल कर सकते हैं।

function [result] = foo(n) 
%[ 
    result = 0; 
    for k = 1:n, 
     pause(1.0); % simulate long processing 
     result = result + 42; 
    end 
%] 
साथ (सी # कोड में कुछ dllimports के पीछे कहीं न कहीं)

:: चलो बुला मान लीजिए

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

अब तक तो अच्छा, मैं (इस के साथ कोई समस्या नहीं है यानी, क्रम intializing लोड हो रहा है '.cft' फ़ाइल, नेट प्रकार के साथ MxArray आगे पीछे वास्ते, आदि ...)

मेरी समस्या

मैं सर्वेक्षण करने मेरी foo समारोह की प्रगति चाहते हैं यू कुछ cancel और 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 
%] 

लेकिन निश्चित रूप से मैं इन कॉलबैक एम-एक के भीतर नहीं, सी # कोड में होना चाहते हैं।

जांच

  1. 'mclmcr.h' हेडर फाइल को देखते हुए, यह इन कार्यों की तरह दिखता है मदद की हो सकती है: दुर्भाग्य से

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

    इन पूरी तरह से गैर-दस्तावेजी हैं और मैं किसी काम का नहीं मामला पाया मैं यह समझने की नकल कर सकता हूं कि वे कैसे काम करते हैं।

  2. मैं भी सी # में एक 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 ऑब्जेक्ट्स को कैसे पैक किया जाता है, मुझे नहीं पता?

इसके अलावा जांच

दिवस + 1

यहां तक ​​कि अगर अभी भी अस्थिर है, मैं matlab के लिए सफल रहा मेरी सी # कोड में कालबैक में और ऐसा लगता है कि mclCreateSimpleFunctionHandle जाना दिशा है।

नोट: नीचे कोड केवल संदर्भ के लिए है। यह आपके संदर्भ में उपयुक्त नहीं हो सकता है। मैं बाद में सरल कोड प्रदान करूंगा (यानी एक बार मुझे स्थिर समाधान मिल जाएगा)।

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

और

// Same signature (but far more elegant from .NET perspective) 
delegate void MCRDelegate(MxArray[] varargouts, MxArray[] varargins); 
  • मैं भी इस तरह क्रम से जुड़ा हुआ:

    1. mxFunctionPtr के हस्ताक्षर करने के लिए देख रहे हैं, मैं दो प्रतिनिधियों को इस तरह बनाया

      [DllImport("mclmcrrt74.dll", EntryPoint = "mclCreateSimpleFunctionHandle", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] 
      static extern IntPtr _mclCreateSimpleFunctionHandle(MCRInteropDelegate fctn); 
      
    2. मान लिया जाये कि 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)); 
      } 
      
    3. अंत में, यह सोचते हैं moduleMCRModule का एक उदाहरण (फिर से, का एक वर्ग है मेरा निम्न स्तर mclFeval एपीआई), मैं foo फ़ंक्शन को कॉल करने में सक्षम था में hInst* संपुटित और इसे इस तरह cancel प्रतिनिधि मेरी नेट में प्रवेश करने के लिए:

      // 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 के साथ गलत दिशा में जा रहा हूं तो कृपया मुझे बताएं।

  • +0

    आप सी # में एक पाश में छोटे टुकड़ों में कार्रवाई को तोड़ने और उन्हें चलाने के अनुभवहीन दृष्टिकोण विचार किया है? –

    +0

    हां मैं इसके बारे में हालांकि (एमसीआर के साथ काम करने के लिए जोड़े गए सभी कोड के बिना यहां नमूना आवेदन प्रदान करने के लिए)। मैं शायद अगले वर्ष की शुरुआत में इस मुद्दे पर वापस आऊंगा, क्योंकि अब भी मैं अन्य गैर संबंधित मुद्दों (डब्ल्यूपीएफ) में नामांकित हूं। – CitizenInsane

    +0

    ठीक है, @ नागरिक Insane, अगर आप कर सकते हैं तो कृपया इस पोस्ट को अपडेट करें, मुझे वास्तव में उस सामान की ज़रूरत है! –

    उत्तर

    1

    समझे यह

    mclCreateSimpleFunctionHandle प्रभावी रूप से आदेश एक सरणी चर (matlab के पक्ष में) बनाने के लिए पर कॉल करने के लिए (के बाहरी तरफ) एक समारोह सूचक के लिए पकड़े सही एपीआई समारोह था। अब मैं रद्दीकरण और प्रगति के उद्देश्यों के लिए अपने सी # कोड में वापस कॉल करने के लिए एम-कोड संकलित करने में सक्षम हूं।

    mclCreateSimpleFunctionHandle के लिए

    सही मार्शलिंग वर्णन किया गया है here

    संबंधित मुद्दे