MATLAB: Can I use ActiveX or OLE automation in Perl to connect to MATLAB

callMATLAB

I would like to use ActiveX or OLE automation in Perl to connect to MATLAB.

Best Answer

You should be able to use any programming language to connect to MATLAB as an automation server as long as it supports passing SAFEARRAYS of doubles. Perl does support this. Below are two simple examples which demonstrates how to open a connection, execute arbitrary code, and put data into MATLAB.
See the help for Win32::OLE to get more details on Perl's ActiveX and OLE automation facilities.
This first example uses PutFullMatrix and GetFullMatrix to exchange in- and outputs between Perl and MATLAB:
# A really basic test of sending data to/from MATLAB using the
# ActiveX interface
use Win32::OLE;
use Win32::OLE::Variant;
# Use existing instance if MATLAB is already running
eval {$ML = Win32::OLE->GetActiveObject('Matlab.Application')};
die "MATLAB not installed" if $@;
unless (defined $ML) {
$ML = Win32::OLE->new('Matlab.Application', sub {$_[0]->Quit;})
or die "Oops, cannot start MATLAB";
}
############################
# Execute a command in ML
############################
# Create a surface plot
$evalString = 'surf(peaks)';
$ML->Execute($evalString);
# Put some data in ML using a string
$ML->Execute('A = magic(4);');
############################
# Put some data into ML
############################
# First create two SAFE_ARRAYs (Can only pass SAFE_ARRAY?)
my $MReal = Variant(VT_ARRAY|VT_R8, [1,2], 2);
my $MImag = Variant(VT_ARRAY|VT_R8, [1,2], 2);
# Set the values
$MReal->Put(1,0,1);
$MReal->Put(1,1,2);
$MReal->Put(2,0,3);
$MReal->Put(2,1,4);
# Put the matrix into MATLAB
$ML->PutFullMatrix('B', 'base', $MReal, $MImag);
# GetFullMatrix is similar but requires unpacking the data
# from MATLAB into the Variant array. The data is passed
# from MATLAB by reference.
# Make real and complex arrays for the data.
my $M2Real = Variant(VT_ARRAY|VT_R8|VT_BYREF, [1,2], 2);
my $M2Imag = Variant(VT_ARRAY|VT_R8|VT_BYREF, [1,2], 2);
# Retrieve the data from MATLAB
$ML->GetFullMatrix('B', 'base', $M2Real, $M2Imag);
# Attempt to get at the contents of returned data
$Element = $M2Real->Get(1,0); # Element in Row 1, Col 1
print("Element in Row 1, Col 1: $Element\n");
# Wait 15 seconds before closing MATLAB
sleep(15);
print('Done waiting...');
The example below uses the Feval method:
# Used modules
use Win32::OLE;
use Win32::OLE::Variant;
use Data::Dumper;
# Start automation-server
my $matlab;
$matlab = Win32::OLE->new('Matlab.Application.Single');
# Declare the Variant correctly for type "[out] VARIANT* result"
my $ret1 = Variant->new(VT_VARIANT|VT_BYREF);
# call Feval
# In MATLAB code we are calling: ret = double('abc')
# This should return: ret = [97 98 99]
$matlab->Feval('double', 1, $ret1, "abc");
# Use Dumper to see what $ret1 looks like
print(Dumper($ret1->Value()));
# Retrieve the values in an easier format
my $val1 = $ret1->Value()->[0]->[0];
# Print the values
printf($val1->[0] . "\n");
printf($val1->[1] . "\n");
printf($val1->[2] . "\n");
printf("\n");
#Close
$matlab->Quit();