passing variables from matlab to c# application - c#

I am trying to pass a cell array (tried a table as well) from Matlab to my C# application. How do I do this?
I can pass a string to my c# application from Matlab but can't seem to pass a vector of strings or a cell array (which contains dates & text)
Matlab Code
DllPath = 'C:\MyPath\MyLibrary.dll';
ass = NET.addAssembly(DllPath);
myCls = AssName.ClassName;
colName = [{'abc'}; {'des'}];
myCls.Foo('sddsdd', colName);
The function below is not useful at the moment I'm just using it to play around with. I can read the tableName variable fine & I can cast the colName variable to a string[].
C#
public int Foo(string tableName, object colName)
{
string[] arr = ((IEnumerable)colName).Cast<object>()
.Select(x => x.ToString())
.ToArray();
Console.WriteLine(tableName);
Console.WriteLine(arr.Length);
return arr.Length;
}

Related

Passing 3D array into MATLAB functions from C# with COM

I was trying to pass a 3D array into a MATLAB function from C# with COM. Here's my code:
// here's the code in C#
MLApp.MLApp matlab = new MLApp.MLApp();
//load function
matlab.Execute(#"cd C:\Users\1303092.local\Matlab\EmGm");
//initialized input and output
int[,,] data1 = new int[2,3,5]{{{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}},{{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}}};
object result1 = null;
object result2 = null;
//use function with the data from C#
matlab.Feval("myfunc", 2, out result1, data1);
//type casting
object[] res1 = result1 as object[];
double[, ,] data2 = res1[1] as double[, ,];
//use function with the casted data from MATLAB
matlab.Feval("myfunc", 2, out result2, data2);
object[] res2 = result2 as object[];
// here's the MATLAB function
function [x,y] = myfunc(a)
x = a;
y = ones(2,3,5);
end
I have inserted a breakpoint at the end of the code to check the value in the variables, which is shown as:
click here for image
It seems C# has no difficulty with taking the return values since it did recognise the returned parameter "y". However, there may be some type casting issue when MATLAB takes the array from C#, since the returned parameter "x" was always been recognised as NULL in C#.
I have also tried 2D array in the exactly same way, and everything was running well. Is the error related to the dimensionality here? Any idea guys?

Where is the data type mismatch when passing arrays from vba to c#?

My C# COM DLL has a method that accepts a float array and a long int array. It returns a float.
From VBA in an MS Access module, I create an array of type single and another of type long, populate them, create the DLL app.class object and then call its method with the two arrays. But I get a "type mismatch" error.
The following is the actual code, but it is simple because I'm trying to work out the communications before adding the "real" code.
C# code:
public float JustTesting(float[] Array1, long[] Array2)
{
return 96.0F;
}
VBA code:
Public Sub Test()
Dim a1(0 To 0) As Single, a2(0 To 0) As Long, sng As Single
a1(0) = 5
a2(0) = 10
Dim o As Variant
Set o = CreateObject("MyApp.MyClass")
sng = o.JustTesting(a1, a2)
Debug.Print CStr(sng)
Set o = Nothing
End Sub
Where is the data type mismatch?
A Long in VBA is only 32 bits, the same was as an int in C#. So your method needs to take an array of ints
public float JustTesting(float[] Array1, int[] Array2)
{
return 96.0F;
}

Call c# method from c++ wrap

I have a c# library with this function:
public static int myGetStrings(String sOne, out String sTemp1, out String sTemp2)
{
sTemp1 = sOne+"1";
sTemp2 = sOne+"2";
return 0;
}
My c++ wrapper call c# library:
char sOneCall[256],sTemp1Call[256],sTemp2Call[256];
sprintf(sOneCall,"this is a test");
int iReturnData = myLibraryClass-> myGetStrings(
Marshal::PtrToStringAnsi((IntPtr) (char *)sOneCall),
Marshal::PtrToStringAnsi((IntPtr) (char *)sTemp1Call),
Marshal::PtrToStringAnsi((IntPtr) (char *)sTemp2Call) );
But when I execute my code the variables "sTemp1Call" and "sTemp1Call" are void.
Why? What is my problem? Where i wrong?
Thank you
I am assuming you are using c++/cli. if so there is no need to use marshal you can just pass a string directly.
String ^sOneCall = "this is a test";
String ^sTemp1Call = "";
String ^sTemp2Call = ""
int iReturnData = myLibraryClass-> myGetStrings(sOneCall,sTemp1Call,sTemp2Call);
Your function has out parameters if you want to get the values after the call you will need to keep around the .net object a PtrToStringAnsi copies the strings to a new String^ object so you will need to copy it back to your native ptr.

String(33, 0) in VB 6.0 and equivalent in C#

What is the meaning of UserName = String(33, 0) in VB 6.0 and what will be the equivalent in C#.
Please help I'm getting error while converting VB 6.0 code into C#.
Thanks in advance.
String in VB6 is a function that returns a string containing a repeating character string of the length specified.
String(number,character)
example:
strTest = String(5, "a")
' strTest = "aaaaa"
strTest = String(5, 97)
' strTest = "aaaaa" (97 is the ASCII code for "a")
In this case, String(33,0) will return a string containing 33 null characters.
The equivalent in C# would be
UserName = new String('\0', 33);
In VB6, that function creates a string that contains 33 characters, all of whom have zero ordinal value.
Typically you do that because you are about to pass the string to some native function which fills out the buffer. In C# the closest equivalent to that would be to create a StringBuilder instance which you would then pass to the native code in a p/invoke function call.
I think that a direct translation of that single line of code is not particularly useful. That code exists in context and I strongly suspect that the context is important.
So, whilst you could create a new C# string with 33 null characters, what would be the point of that? Since the .net string is immutable, you cannot do very much of interest with it. In your VB6 code you will surely be mutating that object, and so StringBuilder is, in my view, the most likely tool for the job.
I believe you are looking for:
UserName = new String((Char)0, 33);
Reference this for what the VB6 method did.
You can create an function that perform this action, or o can do a extenssion of the class String.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(strGen("01",3));
}
//param s is the string that you can generete and the n param is the how many times.
private static string strGen(String s, int n){
string r = string.Empty;
for (int x = 1; x <= n; x++)
r += string.Copy(s);
return r;
}
}

How to create a reference to System.Array holding strings in C#

I have an interesting question regarding C# code.
Basically I have to call a method
BCI2000AutomationLib.IBCI2000Remote.StartupModules(ref System.Array)
Using Visual Studio 2010 the following code compiles and works perfectly:
// Startup modules
string[] modules = new string[3];
modules[0] = "SignalGenerator --local";
modules[1] = "DummySignalProcessing --local";
modules[2] = "DummyApplication --local";
ok_conn = bci.StartupModules(ref modules);
Now porting this to a game engine (e.g. Unity 3D) requires some stricter C# code since it uses Mono C# compiler. So for the same code i get the following compilation error:
The best overloaded method match for
'BCI2000AutomationLib.IBCI2000Remote.StartupModules(ref System.Array)' has some invalid arguments Argument 1: cannot convert
from 'ref string[]' to 'ref System.Array'
Can you please give an advice on how to rewrite this code block to a more strict coding to resolve the stated error?
Change the type of you variable to System.Array
// Startup modules
Array modules = new string[3]
{
"SignalGenerator --local",
"DummySignalProcessing --local",
"DummyApplication --local"
};
ok_conn = bci.StartupModules(ref modules);
Your method StartupModules takes a ref Array as argument ; it can set the variable to any other Array. Not necessarily a string Array, it could be an int[]. That's why you cannot call with a variable typed as Array of string.
String Array program, taking string from user:
class Program
{
static void Main(string[] args)
{
int i,j;
string[] str = new string[10];
Console.WriteLine("Enter the Name of your friends");
for (i = 0; i < 10; i++)
{
str[i] = Convert.ToString(Console.ReadLine());
Console.WriteLine("Array["+i+"]="+str[i]);
}
Console.ReadLine();
}
}

Categories