How do I use MATLAB's actxserver function to pass an array to LABVIEW
1 Comment
Answers (1)
@新云 ,
Your empty outputs are happening because of a fundamental mismatch in how MATLAB and LabVIEW handle arrays through the COM interface. MATLAB sends everything as 2D SAFEARRAYs by default, even simple vectors, but LabVIEW expects true 1D arrays for its array controls. This causes your data to either get lost or not recognized properly.
Here's what you need to change in your code. Before you create the LabVIEW server, add this line:
feature('COM_SafeArraySingleDim', 1);
Then change how you're creating your arrays. Instead of using commas which makes row vectors, use semicolons to make column vectors:
x = [5; 6; 7; 8; 9; 10];
y = {'A'; 'B'; 'C'; 'D'; 'E'; 'F'};
You can also use the transpose operator if you prefer:
x = [5,6,7,8,9,10]';
y = {'A','B','C','D','E','F'}';
The string array issue is also critical. When you write y = ['A','B','C','D','E','F'] MATLAB actually creates a single string 'ABCDEF', not an array of separate strings. You need to use curly braces to make a cell array where each letter is its own element.
Here's your complete code with all the fixes:
feature('COM_SafeArraySingleDim', 1);
lv = actxserver('LabVIEW.Application');
vi_path = 'C:\Users\Admin\Desktop\Labview\TEST\Test Array.vi';
vi = invoke(lv, 'GetVIReference', vi_path);
x = [5; 6; 7; 8; 9; 10];
y = {'A'; 'B'; 'C'; 'D'; 'E'; 'F'};
invoke(vi, 'SetControlValue', 'Array', x); invoke(vi, 'SetControlValue', 'Array 2', y); invoke(vi, 'Run', 1);
pause(2);
output1 = invoke(vi, 'GetControlValue', 'Out1'); output2 = invoke(vi, 'GetControlValue', 'Out2');
disp('Output 1:'); disp(output1);
disp('Output 2:'); disp(output2);
invoke(vi, 'release'); invoke(lv, 'release'); delete(vi); delete(lv);
feature('COM_SafeArraySingleDim', 0);
One really important thing you need to know is that you must reset that feature flag back to 0 when you're done. If you leave it enabled it can interfere with other COM operations, especially Excel-related functions. This is mentioned in various MATLAB Central discussions about passing 1D arrays to ActiveX servers. Just make it a habit to turn it off at the end of your script. You can also check its current state anytime by running
feature('COM_SafeArraySingleDim') without any arguments.
I added a pause after running the VI because COM operations can be weird about timing. Your VI might still be executing when you try to read the outputs, which gives you empty results. Two seconds should be enough for most VIs, but if yours does heavy processing you might need longer. COM operations often fail silently without error messages, which is why you're not seeing any errors even though nothing is working.
If you're still getting empty outputs after trying this, here are some things to check. First, verify your array dimensions are correct by running size(x) and it should show [6,1] not [1,6]. If it shows [1,6] then you're still using row vectors. Second, check if the feature is actually enabled by typing
feature('COM_SafeArraySingleDim') and it should return 1.
Third, make absolutely sure your control names in the MATLAB code match exactly what they're called in LabVIEW because it's case sensitive and even a space or capitalization difference will cause it to fail silently.
Also make sure VI Server is enabled in your LabVIEW settings. Go to Tools, then Options, then VI Server and make sure TCP/IP is enabled. Without this, the whole COM interface won't work properly and you won't get any connection.
You can test if the connection is working by trying to set a single value first, like invoke(vi, 'SetControlValue', 'Array', [5]). If that works but the full array doesn't, you know it's specifically the array format that's the problem. You can also use invoke(vi) without any method name to list all available methods and their signatures, which helps verify you're calling the right thing with the right parameter types.
The technical reason this happens is explained in the official MATLAB documentation on handling COM data. MATLAB represents an m-by-n matrix as a two-dimensional SAFEARRAY where the first dimension has m elements and the second dimension has n elements. So even a simple row vector like [1,2,3] gets passed as a 2D array with dimensions [1,3]. The COM_SafeArraySingleDim feature forces MATLAB to convert single-column matrices to true 1D arrays when passing to COM objects, which is what LabVIEW needs.
If after all this you're still having issues, there are a few alternative approaches discussed in various NI Community forums. You could try using the Call method instead of SetControlValue. It works a bit differently and takes the parameter names and values as cell arrays like this:
paramNames = {'Array', 'Array 2'};
paramVals = {x, y};
invoke(vi, 'Call', paramNames, paramVals);
Some people have reported mixed success with this method. In some forum discussions from years back, users mentioned getting errors like "paramNames type mismatch. Expected 1D array of strings or 1D array of string variants" when using the Call method, so SetControlValue with the feature flag enabled tends to be more reliable.
You could also compile your LabVIEW VI as an ActiveX EXE instead of using VI Server. This gives you more control over the interface and can be more reliable, though it requires more setup work.
Another option is to skip COM entirely and compile your LabVIEW VI as a DLL. You can call it from MATLAB using loadlibrary and calllib. According to discussions on forums, when using DLLs you may need to configure array parameters differently in LabVIEW for them to work with MATLAB. It's more work to set up but gives you direct control over data types without dealing with COM weirdness.
As a last resort, you can use file-based communication where MATLAB writes data to a file and LabVIEW reads it. It's slower and clunkier but it works when nothing else does. Some people use this approach when they need to pass complex data structures that don't map well to COM types.
The bottom line is that COM interface between MATLAB and LabVIEW is finicky because of how they handle arrays differently at a fundamental level. MATLAB treats everything as matrices which are inherently 2D, while LabVIEW has distinct types for 1D arrays, 2D arrays, and matrices. The COM_SafeArraySingleDim feature combined with column vector formatting is the standard solution that most people use successfully once they figure it out. Just remember both parts together, not just one or the other, and always reset the feature when you're done to avoid breaking other COM stuff.
References and Related Resources:
The solution requiring both COM_SafeArraySingleDim and column vectors together comes from MATLAB Answers thread #2074736 at https://www.mathworks.com/matlabcentral/answers/2074736-pass-byref-array-safearray-to-com-server where a user explicitly states "It works only with these two things in combination. I tried them both before several times, but accidently obviously only seperately until now." The official MATLAB documentation on handling COM data at https://www.mathworks.com/help/matlab/matlab_external/handling-com-data-in-matlab-software .html explains that MATLAB represents an m-by-n matrix as a two-dimensional SAFEARRAY where the first dimension has m elements and the second dimension has n elements. Various discussions on NI Community forums like https://forums.ni.com/t5/LabVIEW/matlab-calling-labview-via-activex-passing-parameters/td-p/487447 and https://forums.ni.com/t5/LabVIEW/Calling-LabVIEW-activex-application-from-Matlab/td-p/3030569 document similar issues with passing arrays through ActiveX between MATLAB and LabVIEW. Historical forum discussions at http://www.verycomputer.com/33_18d40140bd2294c2_1.htm mention dispatch errors when trying to pass 1D arrays and note that "The procedure works with non-array VI controls." The timing issue with pause after Run is a common pattern in COM automation that appears across multiple LabVIEW and MATLAB integration discussions where users note that reading outputs immediately after running a VI can return empty results.
0 Comments
See Also
Categories
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!