मेरा प्रश्न 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
%]
लेकिन निश्चित रूप से मैं इन कॉलबैक एम-एक के भीतर नहीं, सी # कोड में होना चाहते हैं।
जांच
'mclmcr.h' हेडर फाइल को देखते हुए, यह इन कार्यों की तरह दिखता है मदद की हो सकती है: दुर्भाग्य से
extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn); extern bool mclRegisterExternalFunction(HMCRINSTANCE inst, const char* varname, mxFunctionPtr fcn);
इन पूरी तरह से गैर-दस्तावेजी हैं और मैं किसी काम का नहीं मामला पाया मैं यह समझने की नकल कर सकता हूं कि वे कैसे काम करते हैं।
मैं भी सी # में एक 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);
मैं भी इस तरह क्रम से जुड़ा हुआ:
mxFunctionPtr
के हस्ताक्षर करने के लिए देख रहे हैं, मैं दो प्रतिनिधियों को इस तरह बनाया[DllImport("mclmcrrt74.dll", EntryPoint = "mclCreateSimpleFunctionHandle", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] static extern IntPtr _mclCreateSimpleFunctionHandle(MCRInteropDelegate fctn);
मान लिया जाये कि
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)); }
अंत में, यह सोचते हैं
module
MCRModule
का एक उदाहरण (फिर से, का एक वर्ग है मेरा निम्न स्तर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
के साथ गलत दिशा में जा रहा हूं तो कृपया मुझे बताएं।
आप सी # में एक पाश में छोटे टुकड़ों में कार्रवाई को तोड़ने और उन्हें चलाने के अनुभवहीन दृष्टिकोण विचार किया है? –
हां मैं इसके बारे में हालांकि (एमसीआर के साथ काम करने के लिए जोड़े गए सभी कोड के बिना यहां नमूना आवेदन प्रदान करने के लिए)। मैं शायद अगले वर्ष की शुरुआत में इस मुद्दे पर वापस आऊंगा, क्योंकि अब भी मैं अन्य गैर संबंधित मुद्दों (डब्ल्यूपीएफ) में नामांकित हूं। – CitizenInsane
ठीक है, @ नागरिक Insane, अगर आप कर सकते हैं तो कृपया इस पोस्ट को अपडेट करें, मुझे वास्तव में उस सामान की ज़रूरत है! –