pass array from matlab to c# via matlab com Automation service - c#

I tried to call some Matlab functions from C# code (.NET) using PutFullMatrix() & GetFullMatrix().
I found that it worked well for passing arrays to the Matlab functions and finishing the calculation in the Matlab files.
The matlab files can also return the correct answer to C# when the return value is scalar (i.e. 1*1 matrix). But when I tried to return an 1*n matrix from Matlab to C#, it always ended up with an exception in Visual studio. It's a type of "System.Runtime.InteroServices.COMException" from mscorlib.dll.
I tried to simplify the function down to a matrix addition, still no luck. Can anyone shed light on why this fails? I am using .NET 4.5 runtime target for x86 CPU.
Below is my problematic C# code:
// Instantiate MATLAB Engine Interface through com
MLApp.MLApp matlab = new MLApp.MLApp();
matlab.PutFullMatrix("basebandData", "base", IData, QData);
matlab.PutFullMatrix("sample_rate", "base", SampleRateR,SampleRateI);
// Using Engine Interface, execute the ML command
// contained in quotes.
matlab.Execute("cd c:\\Users\\****\\Desktop\\MatlabFunctionfolder;");
matlab.Execute("open MATLABFunction.m");
matlab.Execute("dbstop in MATLABFunction.m");
matlab.Execute("[RespRate, HeartRate, HRWav, status]=MATLABFunction(basebandData,sample_rate);");
// matlab.Execute("com.mathworks.mlservices.MLEditorServices.closeAll");
matlab.GetFullMatrix("RespRate", "base", ref RespRateR, ref RespRateI);
matlab.GetFullMatrix("HeartRate", "base", ref HeartRateR, ref HeartRateI);
matlab.GetFullMatrix("HRWav", "base", ref HRWavR,ref HRWavI); // the line where the exception pop up, if don't try to return the array HRWav from matlab function (RespRate, HeartRate, and Status are all 1x1 matrices) the code services well.
matlab.GetFullMatrix("status", "base", ref StatusR, ref StatusI);

Related

Do not show Matlab Workspace when function called in C#

Everytime I call a Matlab function in C#, it has to open the Workspace window first. Is there any way to execute a function without displaying the Workspace? Here's my C# code:
MLApp.MLApp matlab = new MLApp.MLApp();
matlab.Execute(#"cd C:\path\to\folder");
object BestIter = null;
object BestPosition = null;
matlab.PutWorkspaceData("npop", "base", this.Npop);
matlab.PutWorkspaceData("maxiter", "base", this.MaxIter);
matlab.Execute("[bestiter, bestposition] = Algorithm(maxiter, npop);");
matlab.GetWorkspaceData("bestiter", "base", out BestIter);
matlab.GetWorkspaceData("bestposition", "base", out BestPosition);
You may try to compile your Matlab function code using compiler.
After that, you execute your MATLAB .exe file in C# environment using:
Process.Start("yourfile.exe")

Passing bytes as parameter to c#?

I am currently stuck while trying to call a c# methods from python. I am using python 3.2 and not IronPython. I used pip to install the latest version of python.net
Problem occurs (as often discussed) while using ref or out parameters.
Here is my code so far:
import clr
path = clr.FindAssembly("USB_Adapter_Driver")
clr.AddReference(path)
from USB_Adapter_Driver import USB_Adapter
gpio = USB_Adapter()
version2 = ''
status, version = gpio.version(version2)
print ('status: ' + str(status))
print ('Version: ' + str(version))
readMask = bytearray([1])
writeData = bytearray([0])
print (readMask)
print (writeData)
status, readData = gpio.gpioReadWrite(b'\x01',b'\x00',b'\x00')
status, readData = gpio.gpioReadWrite(readMask[0],writeData[0],b'\x00')
status, readData = gpio.gpioReadWrite(readMask[0],writeData[0],)
I have had some major issues getting clr. running at all. But in this exact config it seems to work (I need to save the path to a variable, otherwise it wont work, I also cant type the path the dll in clr.AddReference(path) because this wont work as well)
The c# version method looks like this:
public USB_Adapter_Driver.USB_Adapter.Status version(ref string ver)
My status variable gets a value which works perfectly with the status enum for the c# class.
Problem is: after the call my variable "version" is empty. Why? According to: How to use a .NET method which modifies in place in Python? this should be a legal way to do things. I also tried to use the explicit version but my namespace clr does not contain clr.Reference().
The next (and more severe) problem is pio.gpioReadWrite().Here the info about this one:
public USB_Adapter_Driver.USB_Adapter.Status gpioReadWrite(byte readMask, byte writeData, ref byte readData)
Here I get the error message:
TypeError: No method matches given arguments
It doesn't matter which of the calls I use from above. All of them fail.
Here is the full output of a debugging run:
d:\[project path]\tests.py(6)<module>()
status: 6
Version:
bytearray(b'\x01')
bytearray(b'\x00')
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
d:\[project path]\tests.py(28)<module>()
status, readData = gpio.gpioReadWrite(readMask[0],writeData[0],)
(Pdb) Traceback (most recent call last):
File "D:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\pdb.py", line 1661, in main
pdb._runscript(mainpyfile)
File "D:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\pdb.py", line 1542, in _runscript
self.run(statement)
File "D:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\bdb.py", line 431, in run
exec(cmd, globals, locals)
File "<string>", line 1, in <module>
File "d:\[project path]\tests.py", line 28, in <module>
status, readData = gpio.gpioReadWrite(readMask[0],writeData[0],)
TypeError: No method matches given arguments
Hope one of you has an idea on how to fix this.
Thanks,
Kevin
Python.Net doesn't handle ref/out parameters like IronPython.
status, readData = gpio.gpioReadWrite(b'\x01',b'\x00',b'\x00') call is not quite correct since Python.Net will not return an updated readData as second result.
You can handle ref parameters using reflection. Check out my answer to similar question here
there is a rough code template for your case:
import clr
clr.AddReference("USB_Adapter_Driver")
import System
import USB_Adapter_Driver
myClassType = System.Type.GetType("USB_Adapter_Driver.USB_Adapter, USB_Adapter_Driver")
method = myClassType.GetMethod("gpioReadWrite")
parameters = System.Array[System.Object]([System.Byte(1),System.Byte(0),System.Byte(0)])
gpio = USB_Adapter_Driver.USB_Adapter()
status = method.Invoke(gpio,parameters)
readData = parameters[2]

C# MWMCR:EvaluateFunction error

I am using some matlab functions in c#. When I convert a function to dll, I have two dll. One is Entropy.dll and other one is EntropyNative.dll.
If I use the Entropy.dll I must install the matlab compiler runtime (MCR) to the target computer because it needs MWArray class and it only works with MCR. However I do not want to install MCR to target computer so I have tried to use the EntropyNative.dll because it takes Object instead MWArray as parameter. Thus I do not need to install MCR to each computer. However when I use the native dll, MWMCR:EvaluateFunction error. occurs. That means out of memory exception. File size and functions are same but why this error occurs when I use the native dll?
This (Entropy.dll) one works and error not occurs.
MWNumericArray arr1 = null;
Entropy ent = new Entropy(); //Matlab function.
while(true)
{
double[] arraySegment = new double[window];
arr1=arraySegment;
MWArray function1Result = ent.function1(arr1);
MWArray function2Result = ent.function2(arr1);
arr1=null;
}
If I use EntropyNative.dll out of memory error occurs
Entropy ent = new Entropy();
while(true)
{
double[] arraySegment = new double[window];
double function1Result = ent.function1(arraySegment);
double function2Result = ent.function2(arraySegment);
}
I want to use Native dll so how can I eliminate this error? I tried to force GarbageCollector but it does not help me. Also I have tried ent.WaitForFiguresToDie() and ent.Dispose().
ent.WaitForFiguresToDie():
This method will cause a MATLAB figure window to behave as a modal
dialog box. The method will not return until all the figure windows
associated with this component have been closed.

How to use Vertex Buffer Objects (VBO) with glew and SharpGL using managed to unmanaged call [duplicate]

I'm trying to use VBO in my OpenGL project. I'm using glew library for extensions and glfw for windows handling. When I try to create VBO application crashes and I get
Unhandled exception at 0x00000000 in symulator3C.exe: 0xC0000005:
Access violation
in function glGenBuffersARB. Here's my code:
GLuint vboId1=0; //this is global variable
void createVBO(){
normalsVBO = (float *) malloc(sizeof(float)*3*(SIZE_X-1)*SIZE_Y*2);
verticesVBO = (float *) malloc(sizeof(float)*3*(SIZE_X-1)*SIZE_Y*2);
if(normalsVBO==NULL) exit(-1);
if(verticesVBO==NULL) exit(-1);
glGenBuffersARB(1, &vboId1); //HERE IT CRASHES!
// bind VBO in order to use
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId1);
...
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float)*3*(SIZE_X-1)*SIZE_Y*2, verticesVBO, GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY); // activate vertex coords array
glVertexPointer(3, GL_FLOAT, 0, 0);
}
I don't know what's wrong. Of course before calling this function I call glewInit() and result is success.
EDIT: I'm using Visual Studio 2010
Since your program fails at the first use of a VBO related function, it sounds like you either didn't initialize GLEW properly (by calling glewInit once the GL context is created and active) or your hardware just doesn't support VBOs.
Just check if your hardware supports GL_ARB_vertex_buffer_object or if the OpenGL version is at least 1.5, in which case you can use the core versions of the VBO functions (without the ARB suffix, but you still need a properly initialized GLEW for these, of course):
printf("%s\n", glGetString(GL_VERSION));
if(!strstr(glGetString(GL_EXTENSIONS), "GL_ARB_vertex_buffer_object"))
//no VBO extension
And make sure you work with a recent graphics driver. If you work with the Windows default driver, it may only support OpenGL 1.1.

Use C++ Component Object Model in C#

I am trying to build a COM Library in C++, using a C# project for testing. Some methods need to return strings to the caller. On calling these methods from C# I get this: "Access violation reading at location ..."
This is the C++ code from my testproject (apart from all the stuff generated by VS 2010 ATL)
//COMTest.idl
[id(1)] HRESULT Test([out,retval] BSTR* ret);
//Program2.h
STDMETHOD(Test)(BSTR* ret);
//Program2.cpp
STDMETHODIMP CProgram2::Test(BSTR* ret)
{
BSTR tmp = (BSTR)CoTaskMemAlloc(sizeof(wchar_t) * 2);
tmp[0] = L'H';
tmp[1] = L'\0';
*ret = (BSTR)tmp;
return S_OK;
}
In C# I just referenced the DLL from the COM-Tab, turned "Embed Interop Types" off, because it caused errors, and ran this:
static void Main(string[] args)
{
COMTestLib.Program2Class instance = new COMTestLib.Program2Class();
string tmp = instance.Test(); //Where the error occurs
Console.WriteLine(tmp); //This is not reached
Console.Read();
}
The error occurs after leaving the Test-Method. I debugged the C++ code from within my C# project and the values are placed in the correct locations. I do not get the error if I try to return 0 (gives null in C#), even if I still allocate memory like in the example.
I can not make sense of the address, which the access violation complains about. It is neither the address I am allocating nor any other address used in the method. What also seems weird to me is that the CoTaskMemAlloc-Function always returns addresses with the first byte set to zero (0x00XXXXXX), but that might just be a COM thing.
I ran out of ideas and I cant find much information on this (except for basic COM tutorials) anywhere. Can anyone help?
BSTRs require extra memory (to keep track of the string len) so must use SysAllocString() function to allocate BSTRs (or use one of the "smart" BSTR classes).
So your original code should read like:
//Program2.cpp
STDMETHODIMP CProgram2::Test(BSTR* ret)
{
*ret = SysAllocString(L"H");
return S_OK;
}
A good reading about BSTRs: http://blogs.msdn.com/b/ericlippert/archive/2003/09/12/52976.aspx
Check that your COM project and test project are both STA. Check the bitness too. What if you replace BSTR by LPSTR ?

Categories

Resources