I am trying to call a Matlab function from c# by using the instructions in this Matlab help website.
Using the method and the example in the Matlab website went well but now trying to redo everything with writing a separated class for calling the Matlab function, and call the method in the main class and give the parameters values to get results.
When doing so, an error in reusing the variables happend.
The following is the class that is calling the Matlab function.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace fromMatlab
{
public class Class1
{
public static Data FromMatLab(double a, double b, string c)
{
MLApp.MLApp matlab = new MLApp.MLApp();
matlab.Execute(#"cd c:\Users\abdhab\Documents\MATLAB");
object result = null;
matlab.Feval("myfunc", 2, out result, 3.14, 42.0, "world");
object[] res = result as object[];
object x = res[0];
object y = res[1];
return new Data { X = x, Y = y };
}
}
}
The class that deals with the variables and the constructers.
namespace fromMatlab
{
public class Data
{
public object X { get; set; }
public object Y { get; set; }
}
public struct DataStruct
{
object X;
object Y;
}
}
The Main class.
using System;
using System.Collections.Generic;
using System.Text;
namespace fromMatlab
{
class Program
{
static void Main(string[] args)
{
double a = 1;
double b = 2;
string c = "world";
object data =Class1.FromMatLab(a, b, c);
object X = data.X;
object Y = data.Y;
Console.WriteLine(X);
Console.WriteLine(Y);
Console.ReadLine();
}
}
}
The error is the compiler error CS1061 and it occur in the following lines.
object X = data.X;
object Y = data.Y;
The Matlab function is the following:
function [x,y] = myfunc(a,b,c)
x= a+b;
y = sprintf('Hello %s',c);
You are assigning a result of Class1.FromMatLab(a, b, c); to a variable of type object, which doesn't have X or Y property. If you change object data to Data data or var data, the compiler error should disappear.
Related
I am using excel-DNA example as basis for this test.
I want excel to show my updated data in cell B1 every 1 second.
This works fine for about the first 5 secs, then I get a timer and the have to wait for function finish to see only the last value.
How do I force the update to be shown on the spreadsheet at each cycle of the loop?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExcelDna.Integration;
using System.Threading.Tasks;
using System.Diagnostics;
namespace BTPRTD
{
class Program
{
static void Main(string[] args)
{
}
}
public static class MyFunctions
{
public static MouseData MData;
[ExcelFunction(Description = "My first .NET function")]
public static string SayHello(string name)
{
//Debugger.Launch();
MData = new MouseData ();
Task.Factory.StartNew(() =>
{
ExcelAsyncUtil.QueueAsMacro(() =>
{
KeepWritingData();
});
});
return "Hello " + name;
}
public static void KeepWritingData()
{
var refB1 = new ExcelReference(0, 0, 1, 1, "Sheet1");
string dataTxt = "";
for (int i = 0; i < 100; i++)
{
try
{
MouseData .CurrentPriceData CPD = MData.GetCurrentPriceNT("White mouse");
dataTxt = CPD.AsString();
}
catch (Exception)
{
dataTxt = "Data Unavailable";
}
refB1.SetValue("Ding: " + i + " " + dataTxt);
System.Threading.Thread.Sleep(1000);
}
}
}
}
Excel supports a type of worksheet function called RealTimeData (RTD), which is what you should use for your scenario.
Follow the examples in the "Samples" GitHub repository. In special, take a look at the RtdClocks example that uses an Observable Timer:
public static class RtdClock
{
[ExcelFunction(Description = "Provides a ticking clock")]
public static object dnaRtdClock_Rx()
{
string functionName = "dnaRtdClock_Rx";
object paramInfo = null; // could be one parameter passed in directly, or an object array of all the parameters: new object[] {param1, param2}
return ObservableRtdUtil.Observe(functionName, paramInfo, () => GetObservableClock() );
}
static IObservable<string> GetObservableClock()
{
return Observable.Timer(dueTime: TimeSpan.Zero, period: TimeSpan.FromSeconds(1))
.Select(_ => DateTime.Now.ToString("HH:mm:ss"));
}
}
I've been banging my head on this all weekend. Basically I am doing a code kata for Game of Life and it involves reading in a text file. I take in that text file which contains two dimensional representation of the grid and stores all the points in a List of List's. I am trying to mock the text input obtained from the file to just be '\n' a new line so I can write unit tests checking that there is a new List being created within the List of Lists. I have created a file wrapper to handle the reading of the text file and that is what I am trying to mock. The code complies fine but the test fails with the error message "System.ArgumentException : The specified path is not of a legal form". It seems to still be expecting a file path but the mocking should change this behaviour right? Any help would be appreciated.
using System.Collections.Generic;
namespace GameOfLife
{
public class InitializeGrid
{
public InitializeGrid ()
{
}
public List<List<char>> CreateCharMatrix (string filePathName)
{
// Reads in the text file containing the grid data
FileWrapper fileWrapper = new FileWrapper ();
string inputGridTextFile = fileWrapper.ReadTextFromFile (filePathName);
// Creates character matrix and initialises the first sub List
List<List<char>> charMatrix = new List<List<char>> ();
charMatrix.Add(new List<char>());
int rowIndex = 0;
int colIndex = 0;
foreach (char cell in inputGridTextFile) {
if (cell == '\n') {
charMatrix.Add (new List<char> ());
rowIndex++;
colIndex = 0;
} else {
charMatrix [rowIndex] [colIndex] = cell;
colIndex++;
}
}
return charMatrix;
}
}
}
using NUnit.Framework;
using System;
using System.Collections.Generic;
using Moq;
namespace GameOfLife
[TestFixture()]
public class InitializeGridTest
{
[Test()]
public void CreateCharMatrix_EnsuresThatWhenEndOfLineReachedNewSubListCreated()
{
//Arrange
InitializeGrid initializeGrid = new InitializeGrid ();
List<List<char>> charMatrix;
string filePathName = " ";
Mock<IFileWrapper> mockFileWrapper = new Mock<IFileWrapper> ();
mockFileWrapper.Setup<string> (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("\n");
mockFileWrapper.Setup (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("\n");
//Act
charMatrix = initializeGrid.CreateCharMatrix (filePathName);
int countProvingAnAdditionalListHasBeenAdded = charMatrix.Count;
//Assert
Assert.AreEqual (2, countProvingAnAdditionalListHasBeenAdded);
}
}
using System;
using System.IO;
namespace GameOfLife
{
public class FileWrapper : IFileWrapper
{
public string ReadTextFromFile(string path)
{
return File.ReadAllText (path);
}
}
}
using System;
namespace GameOfLife
{
public interface IFileWrapper
{
string ReadTextFromFile(string filePathName);
}
}
Looking at your code the InitializeGrid is still using the FileWrapper class. It is not using a mocked class so the code is still trying to use the file system.
Your InitializeGrid class needs to use the IFileWrapper interface and not the FileWrapper class. I would look at passing the IFileWrapper interface into the constructor of the InitializeGrid class.
public class InitializeGrid
{
IFileWrapper fileWrapper;
public InitializeGrid (IFileWrapper fileWrapper)
{
this.fileWrapper = fileWrapper;
}
public List<List<char>> CreateCharMatrix (string filePathName)
{
string inputGridTextFile = fileWrapper.ReadTextFromFile (filePathName);
// More code here...
}
}
In your test you would construct the InitializeGrid object using the mocked IFileWrapper by passing the mockFileWrapper.Object to its constructor.
List<List<char>> charMatrix;
string filePathName = " ";
Mock<IFileWrapper> mockFileWrapper = new Mock<IFileWrapper> ();
mockFileWrapper.Setup<string> (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("\n");
mockFileWrapper.Setup (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("\n");
InitializeGrid initializeGrid = new InitializeGrid (mockFileWrapper.Object);
i am a new programmer here. I have the following code. I passed the object by value, but when i printed the results, i got this
elf attacked orc for 20 damage!
Current Health for orc is 80
elf attacked orc for 20 damage!
Current Health for orc is 80
this got me confused about passing by reference because I did not expect the health in the main to be 80 since i passed the object by value. Can someone explain how the result for health in the program main function was 80 instead of 100?
//MAIN class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace passingTest
{
class Program
{
static void Main(string[] args)
{
// Enemy Objects
Enemy elf = new Enemy("elf", 100, 1, 20);
Enemy orc = new Enemy("orc", 100, 1, 20);
elf.Attack(orc);
Console.WriteLine("{0} attacked {1} for {2} damage!", elf.Nm, orc.Nm, elf.Wpn);
Console.WriteLine("Current Health for {0} is {1}", orc.Nm, orc.Hlth);
Console.ReadLine();
}
}
}
// Enemy Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace passingTest
{
class Enemy
{
// variables
string nm = "";
int hlth = 0;
int lvl = 0;
int wpn = 0;
public string Nm
{
get { return nm; }
set { nm = value; }
}
public int Wpn
{
get { return wpn; }
set { wpn = value; }
}
public int Hlth
{
get { return hlth; }
set { hlth = value; }
}
public Enemy(string name, int health, int level, int weapon)
{
nm = name;
hlth = health;
lvl = level;
wpn = weapon;
}
public void Attack(Enemy rival){
rival.hlth -= this.wpn;
Console.WriteLine("{0} attacked {1} for {2} damage!", this.nm, rival.nm, this.wpn);
Console.WriteLine("Current Health for {0} is {1}", rival.nm, rival.hlth);
}
}
}
In C#/.NET, whether an object is passed by reference or by value is determined by the type of the object. If the object is a reference type (i.e. it is declared with class), it is passed by reference. If the object is a value type (i.e. it is declared with struct) it is passed by value.
If you change the declaration of Enemy to
struct Enemy
you will see pass-by-value semantics.
In C# Classes are considered reference types. A reference type is a type which has as its value a reference to the appropriate data rather than the data itself. For instance, consider the following code:
Here;s a link with more information on the subject: http://jonskeet.uk/csharp/parameters.html
I am trying to understand Reflection in c# and I am trying to get the following code to work. The first method (GetUserName) works but the second method (AddGivenNumbers) is giving me an exception error of "parameter type mismatch".
I created a class library with the 2 methods and am trying to use reflection in main console application.
Class Library Code:
namespace ClassLibraryDELETE
{
public class Class1
{
public string GetUserName(string account)
{
return "My name is " + account;
}
public int AddGivenNumbers(int num1, int num2)
{
return num1 + num2;
}
}
}
Code in my main console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace ConsoleApplicationDELETE_REFLECTION
{
class Program
{
static void Main(string[] args)
{
Assembly assemblyInstance = Assembly.LoadFrom(#"C:\Users\xyz\Desktop\Debug\ClassLibraryDELETE.dll");
Type Class1Type = assemblyInstance.GetType("ClassLibraryDELETE.Class1");
object class1Instance = Activator.CreateInstance(Class1Type);
MethodInfo getMethodFullName = Class1Type.GetMethod("GetUserName");
string[] parameter = new string[1];
parameter[0] = "John Doe";
string userName = (string)getMethodFullName.Invoke(class1Instance, parameter);
Console.WriteLine("User Name = {0}", userName);
Assembly assemblyInstance2 = Assembly.LoadFrom(#"C:\Users\xyz\Desktop\Debug\ClassLibraryDELETE.dll");
Type ClassType2 = assemblyInstance.GetType("ClassLibraryDELETE.Class1");
object class1Instance2 = Activator.CreateInstance(ClassType2);
MethodInfo getMethodFullName2 = ClassType2.GetMethod("AddGivenNumbers");
//object[] parameters = new object[2];
//parameters[0] = 8;
//parameters[1] = 4;
object[] args2 = new object[] { 1, 2 };
object result = getMethodFullName.Invoke(class1Instance2, args2);
Console.WriteLine("Sum of the two numbers is {0}", result);
Console.ReadLine();
}
}
}
You have a typo
object result = getMethodFullName.Invoke(class1Instance2, args2);
You should have been targeting getMethodFullName2, otherwise you're trying to execute the first function (which takes 1 argument) with 2 arguments.
Working example: http://rextester.com/WBFYB30834
During defineMapCellPositions() and defineMapCellWalls(), map.cols and map.rows change from values such as 4 and 5 to 0, only for the step through of the methods. A step through the debugger confirms this. Why is this?
Any Help Appreciated, thanks!
Whole Map class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public class Map
{
public Map()
{
}
public int rows { get; set; }
public int cols { get; set; }
public int boardXPos { get; set; }
public int boardYPos { get; set; }
public int squareSize { get; set; }
private List<List<int>> m_cellPositions = new List<List<int>>();
public List<List<int>> cellPositions
{
get
{
return m_cellPositions;
}
set
{
m_cellPositions = value;
}
}
private List<List<int>> m_cellWalls = new List<List<int>>();
public List<List<int>> cellWalls
{
get
{
return m_cellWalls;
}
set
{
m_cellWalls = value;
}
}
}
Start of MapController Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public class MapController
{
public MapController()
{
}
Map map = new Map();
Method to set map.cellWalls
public void defineCellWallsList()
{
//map.cellWalls.Clear();
for (int row = 0; row < (map.rows * map.cols); row++)
{
map.cellWalls.Add(new List<int> { 0, 0 });
}
}
Method to set map.cellPositions
public void defineCellPositionsList()
{
//map.cellPositions.Clear();
for (int row = 0; row < map.rows; row++)
{
for (int col = 0; col < map.cols; col++)
{
map.cellPositions.Add(new List<int> { col, row });
}
}
}
To expose the instance of Map in your MapController either make it a public field, or put it in a property. example:
public class MapController
{
public MapController()
{
}
//here you make it "public" so it is visible to outside classes
public Map map = new Map();
// the rest of your code for this class...
Then to access that instance (assuming you are holding onto an instance of the controller)
var controller = new MapController();
controller.map.rows = 5; // now you can access that instance of map.
controller.map.rows = 123;
Now, to inject the Map into the controller (meaning that it is newed up somewhere else in your code, and the same instance can then be shared accross multiple classes using similar injection procedures) you would do something like this...
public class MapController
{
//here you make it "private" cause it doesn't need to be public anymore,
//you also don't new it up here, you are passing in a new on during construction.
private Map map;
public MapController(Map map)
{
this.map = map
}
// the rest of your code for this class...
Now in the code where you new up the objects and stuff...
var map = new Map();
var controller = new MapController(map);
map.rows = 5; // now you can access that instance of map.
map.rows = 123;
// and you can easily share that same instance with other classes
var otherClass = new SomeOtherClassThatNeedsTheMap(map);