MATLAB: How to call GetWorkspaceData through late binding in C#

MATLAB

I have written a C# Application which call MATLAB's COM Automation Server through late-binding:
using System;
using System.Reflection;
namespace MatlabExample
{
class Program
{
static void Main(string[] args)
{
// Establish late binding connection to MATLAB
Type matlabApp = Type.GetTypeFromProgID("Matlab.Application");
object matlab = Activator.CreateInstance(matlabApp);
// Transfer some data to MATLAB
matlabApp.InvokeMember("PutWorkspaceData", BindingFlags.InvokeMethod, null, matlab, new object[] {
"A","base", new double[2,2] { {1,2},{3,4}} });
// Compute square of matrix
matlabApp.InvokeMember("Execute", BindingFlags.InvokeMethod, null, matlab, new object[] {
"B = A^2;" });
// Attempt to retrieve data
object[] arguments = new object[] { "B", "base", null };
matlabApp.InvokeMember("GetWorkspaceData", BindingFlags.InvokeMethod, null, matlab, arguments);
// arguments[2] stays null however so the following fails
Console.WriteLine(arguments[2].ToString());
}
}
}
I can successfully use PutWorkspaceData and Execute but am unable to retrieve the results using GetWorkspaceData.

Best Answer

The IDL function signature of GetWorkspaceData is:
HRESULT GetWorkspaceData([in] BSTR varname, [in] BSTR workspace, [out] VARIANT* pdata)
So the third parameter is marked as out.
When working with out (or ref) parameters in combination with InvokeMember and COM and you want to be able to retrieve the modified values you need to work with ParameterModifiers:
// Retrieve data
object[] arguments = new object[] { "B", "base", null };
// Create ParameterModifier object for 3 parameters
ParameterModifier pm = new ParameterModifier(3);
// Allow parameter 3 to be modified
pm[2] = true;
// Call InvokeMember with the ParameterModifier
matlabApp.InvokeMember("GetWorkspaceData", BindingFlags.InvokeMethod, null, matlab,
arguments,new ParameterModifier[] {pm},null,null);
// The following should now work
Console.WriteLine(arguments[2].ToString());