Integrating Matlab code into C# application - c#

I have developed some matlab functions for voice authentication.
And now I want to use an application to provide input to those functions and execute those values in the matlab functions and get the results again to the application.
Is there any particular way to do this?

Mathworks has a product called the MATLAB Builder NE for doing just this.
It will build a DLL for either .NET or COM, wrapping the MATLAB code. You can then execute the code on any machine which has the MATLAB runtime (free) installed on it.
From what I've seen, this really just creates a DLL with the proper overloads for every function in your code, and helps you convert from .NET types into MATLAB arrays. In the end, it is still calling native MATLAB code and running it on the MATLAB runtime, so it is something that could be self-implemented as well (although it would take some probably significant effort).

This extract is taken from my blog post which demonstrates the procedures needed to compile a .NET dll from MATLAB CODE http://scriptbucket.wordpress.com/category/matlab/ this should be of some help to you.
using System;
using System.Windows.Forms;
using MathWorks.MATLAB.NET.Arrays;
using calculator;
namespace DemoCalculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var calc= new demo();
MessageBox.Show(calc.calculator((MWCharArray)textBox1.Text)[1].ToString());
}
}
}

The following links can help you with your problem. The first one has used a matlab program in a c# program using COM objects and the second link has described 3 ways to communicate with matlab in a program.
http://www.codeproject.com/Articles/594636/Using-Matlab-from-a-Csharp-application
http://www.codeproject.com/Articles/5468/1-2-3-ways-of-integrating-MATLAB-with-the-NET

Related

Application .NET which compile code in Windows form

I have problem. I can't find mechanism in .Net which allow me compile code in Windows form.
I want have 1 textbox with code and later compiled code show in another box.
How I can do this?
It sounds like you want to use a C# compiler from within your Windows Forms app, but I'm unsure what your other box would show.
If you're looking for just compiling and visually displaying IL, there are certainly ways to call Roslyn from Windows Forms.
If you're looking to dynamically generate a GUI, your options are a little less clear. I would consider exposing your own wrapper functions to another language. I would consider using Moonsharp to compile Lua code on the fly. IronPython would also work. I'm unfamiliar with whether F# language services could be invoked in a similar way, but these are options I'd consider.
If you're specifically looking to compile C# and use the results to display a WinForms GUI, you'll need to use CodeDOM. CodeDOM is a pretty deep rabbit hole even if it's powerful, and it won't be easy to sandbox any GUI it renders to the output container you have in mind.
As has been mentioned, compiling code using Roslyn is certainly the way forward.
If you wish to see some output by executing the compiled code you may wish to create an abstract class for script writing which provides an entry point and a way of reporting output. You could then compile the script into a dll and use reflection to load the output assembly, instantiate an instance of your class (a class that implements ScriptTemplate below) and execute via the entry point.
abstract class ScriptTemplate
{
public abstract void Main();
public string Output
{
get;
protected set;
}
}
Your form could then write the Output property to a text box for example.
class Script : ScriptTemplate
{
public override void Main()
{
Output = "Hello world!";
}
}

Communicate with main window class from CodeDom compiled code C# Wpf

As the title suggests I am having a bit of trouble communicating with my wpf application's MainWindow.cs class during runtime when the code compiles.
Context:
This is a application I am writing for myself that utilizes CodeDom's compiler to compile code stored in xml format at runtime or in a triggered event(like a button or voice command)
The compiler is working neatly but I have been stuck at communicating with my classes from the original application.(MainWindow.cs)
I would like to be able to call functions and access variables from within the runtime compiled CodeDom Scripts. I have found method invoking but I don't quite understand how it works yet, any help would be appreciated!
Example of what I want to do:
Main Window Class Example
namespace WpfOverlay
{
public partial class MainWindow : Window
{
public string AccessThis;
public void ExampleFunctionToAccess(string InputString)
{
AccessThis = InputString;
}
}
}
And access that class to call ExampleFunctionToAccess(); from a CodeDom Compiled script/class in a different namespace (if possible I wouldn't mind having them in the same namespace)
The fact that you compile it at runtime has no bearing on your actual problem, what you actually want is to implement any of the myriad forms possible of IPC.
I recommend an UDP client/server approach, it's relatively easy to implement robustly.

System.InvalidCastException trying to build a COM client and a COM server in C#

I'm trying to build a COM client which has to instantiate a in-process COM server in C#.
I made two C# projects: one for the client and one for the server. Both projects use x86 target platform and the latter has the option "Register for COM interop" set. I'm using Visual Studio 2013 on a 64bit Windows 7 and compiling with .net 4.
This is the server code:
using System.Runtime.InteropServices;
namespace ComRibbonApplicationMenuServer
{
[ComVisible(true)]
[Guid("CCF43AAC-0822-4C36-90FD-2AFF7B94E71D")]
public interface IComRibbonApplicationMenuServer
{
[DispId(1)]
int OpenWindow();
}
[ComVisible(true)]
[Guid("38B1DE85-BC15-48E1-AFAF-4A7EA506256B")]
[ClassInterface(ClassInterfaceType.None)]
public class ComRibbonApplicationMenuServerClass : IComRibbonApplicationMenuServer
{
public ComRibbonApplicationMenuServerClass()
{
// Needed for COM
}
public int OpenWindow()
{
return 33;
}
}
}
And this is the client:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ComRibbonApplicationMenuClient
{
[Guid("CCF43AAC-0822-4C36-90FD-2AFF7B94E71D")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
interface IComRibbonApplicationMenuServer
{
void OpenWindow();
}
[ComImport, Guid("38B1DE85-BC15-48E1-AFAF-4A7EA506256B")]
class ComRibbonApplicationMenuServerClass
{
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ComRibbonApplicationMenuServerClass comServerClass = new ComRibbonApplicationMenuServerClass();
IComRibbonApplicationMenuServer comServer = (IComRibbonApplicationMenuServer)comServerClass;
comServer.OpenWindow();
}
}
}
The istruction new ComRibbonApplicationMenuServerClass(); throws an InvalidCastException HResult=-2147467262.
What can I do?
Edit:
Thanks Hans for your answer.
If I understand correctly, as I suspected, it is not allowed to create a dotnet COM client for a dotnet COM server without some hacking.
As you have guessed, what I'm trying to do is to test a dotnet program which I've found to work properly when executed as a standalone application, but that crashes (only in Windows XP) when executed by another application via COM.
In order to reproduce the problem I need to build a simple test program that has to start the server and call a method which executes some instructions which, probably, are causing a stack overflow exception. Both programs are using a GUI which maybe part of the problem.
To keep things simple I tried first to make winform program for the COM client, but, reading your anwser, I'm thinking that I have to make a MFC application for testing the COM scenario. What do you think?
throws an InvalidCastException HResult=-2147467262.
You are getting a much more detailed exception message, it will tell you that the cast failed due to the E_NOINTERFACE error return. Which is normally pretty hard to diagnose, except in this case, there really is no interface. The declarations you used in the client are a gross mismatch with the ones used in the server:
the ComRibbonApplicationMenuServerClass declaration in the client doesn't implement any interface. Since you arbitrarily omitted [ClassInterface(ClassInterfaceType.None)], .NET will auto-generate one. It has an random [Guid] that will never match the server's, thus generating the E_NOINTERFACE error.
you arbitrarily gave the client side interface declaration the [InterfaceType(ComInterfaceType.InterfaceIsDual)] attribute. The server omits it and thus uses the default which is ComInterfaceType.InterfaceIsIDispatch. Such an interface can only be called late-bound, the client has to use IDispatch. Which means that if you fix the problem in the first bullet, it will still fail because the server doesn't actually implement the interface. In C#, you'd have to use the dynamic keyword to use such a server.
Clearly it is absolutely essential that the client uses the exact same declarations as the server, normally ensured by using Tlbexp.exe on the server to generate a type library. It is somewhat guessable why you got into this pickle, the IDE will refuse to let you add a reference to the type library, it can see that the server was implemented in .NET and tell you to add a normal .NET reference instead. Which is rather good advice, it doesn't make sense to use COM at all when the normal .NET way already works in a much superior way.
You can fool the machine by using a decompiler on the interop library that Tlbexp.exe generates and copy/paste them into the client, thus making sure you have an exact match. Or by using late-binding with the dynamic keyword in the client app, required anyway because the server uses ComInterfaceType.InterfaceIsIDispatch. Also much less painful since you don't have to repeatedly do the copy/paste step when you alter the server.
But you do need to keep in mind that you are not actually using COM when you do this, the CLR itself is smart enough to see that there's .NET code talking to .NET code and will skip creating the RCW and CCW. So if you are doing this for testing, do keep in mind that you are not actually testing the server the way it is going to be used in a real client app. You might as well test it by actually adding a .NET reference.

Calling a C# library from python

Anyone can share a working example on how to call a simple C# library (actually its WPF) from python code? (I have tried using IronPython and had too much trouble with unsupported CPython library my python code is using so I thought of trying the other way around and calling my C# code from Python).
Here is the example I was playing with:
using System.Runtime.InteropServices;
using System.EnterpriseServices;
namespace DataViewerLibrary
{
public interface ISimpleProvider
{
[DispIdAttribute(0)]
void Start();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class PlotData : ServicedComponent, ISimpleProvider
{
public void Start()
{
Plot plotter = new Plot();
plotter.ShowDialog();
}
}
}
Plotter is a WPF windows that plots an Ellipse
I don't know how to call this code from my python all. Any suggestions?
It is actually pretty easy. Just use NuGet to add the "UnmanagedExports" package to your .Net project. See https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports for details.
You can then export directly, without having to do a COM layer. Here is the sample C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;
class Test
{
[DllExport("add", CallingConvention = CallingConvention.Cdecl)]
public static int TestExport(int left, int right)
{
return left + right;
}
}
You can then load the dll and call the exposed methods in Python (works for 2.7)
import ctypes
a = ctypes.cdll.LoadLibrary(source)
a.add(3, 5)
Since your post is tagged IronPython, if you want to use the sample C# the following should work.
import clr
clr.AddReference('assembly name here')
from DataViewerLibrary import PlotData
p = PlotData()
p.Start()
Python for .Net (pythonnet) may be a reasonable alternative to IronPython in your situation.
https://github.com/pythonnet/pythonnet/blob/master/README.rst
From the site:
Note that this package does not implement Python as a first-class CLR
language - it does not produce managed code (IL) from Python code.
Rather, it is an integration of the CPython engine with the .NET
runtime. This approach allows you to use use CLR services and continue
to use existing Python code and C-based extensions while maintaining
native execution speeds for Python code.
Also
Python for .NET uses the PYTHONPATH (sys.path) to look for assemblies
to load, in addition to the usual application base and the GAC. To
ensure that you can implicitly import an assembly, put the directory
containing the assembly in sys.path.
This package still requires that you have a local CPython runtime on your machine.
See the full Readme for more info https://github.com/pythonnet/pythonnet
This project has been developed for that exact purpose - use C# classes in regular Python
https://bitbucket.org/pydotnet/pydotnet/wiki/Home
All you need to do is to install either MSI or EGG into your CPython. PyDotnet is Python module, so the executable stays regular python.exe from your installation of Python or Anaconda. Supported both 32bit and 64bit.
Unlimited access to all C# classes, methods with output and ref parameters, generic classes and generic methods, extension methods, private members.
Overloaded assembly loader with customized mechanics for searching assemblies.
.NET runtime type information convertible to class object, which can be instantiated as any other class.
Special import mode designed especially for Python interactive shell, which allows you to discover available assemblies, namespaces, classes, methods, etc.
I'm waiting for feedback:)

Java .NET interop

Alright, I've been digging at this for awhile and am looking for input.
I need a Java application that can load and unload native libraries, simple enough, C/C++/Java/Scripts/Executables/etc. is no real problem using JNI and other built in features.
However, I need the ability to also load .NET libraries, this has been crazy frustrating. My first attept was to use JNI and call a C++ wrapper as is below:
Java:
this.Lib = (LibHandler)Native.loadLibrary("MyLib", LibHandler.class);
The CPP:
#include <jni.h>
#using <MyLibCSharp.dll>
#include <vcclr.h>
#include <msclr\marshal.h>
using namespace msclr::interop;
using namespace System::Runtime::InteropServices;
using namespace System;
extern "C"
{
JNIEXPORT jstring JNICALL Java_Test(JNIEnv * env)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
JNIEXPORT jstring JNICALL Java_Test2(JNIEnv * env, jobject jobj)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
}
This would continously fail to even be loaded by the system, I can swap the files so that MyLib.dll is actually the C# one, and it successfully loads it (but fails to find any functions being as it's not a native C library and I don't think .NET can export like C++ can), so I'm not having file location issues.
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'MyLib.dll': The specified module could not be found.
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at EntryPoint.main(EntryPoint.java:31)
I figured I'd try to compile the C# library as a COM object and call it that way, alas:
ActiveXComponent comp = new ActiveXComponent("MyLib.Class1");
Fails with:
Exception in thread "main" com.jacob.com.ComFailException: Can't co-create object
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:99)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
at EntryPoint.main(EntryPoint.java:33)
C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace MyLib
{
[Guid("4F3A0A13-4D2B-4DE6-93EA-D6861C230290"),
ComVisible(true)]
public interface ITest
{
[DispId(1)]
string Test();
}
[Guid("A78C5820-3E4B-49B3-8C8E-63DD12346410"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)]
public interface ITestEvents
{
}
[Guid("3ECD46AE-E8F4-4B62-B9DC-DD7F6CB435E2"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(ITestEvents)),
ComVisible(true)]
public class Class1 : ITest
{
public string Test()
{
return "This is my C# DLL COM returning a string! heh!";
}
}
}
I can see the COM is registered, I can browse it with oleview.exe, but I can't call it from vbScript... I'm confused on that one, so I'm completely out of ideas, this has really been racking my brain all day.
I'd like to get away from COM, but I need to keep the implmentation fairly simple (the libraries wont be developed by us, so I don't want to drop a bunch of C/C++ code into the lap of VB6 developers).
I'd be fine with going back to the CLI C++ implementation method, being as it's so straightforward almost anyone can do it.
Any ideas would be extremely appreciated, thanks.
Edit:
I can't use System.LoadLibrary, wont let me unload libraries like Native.LoadLibrary with an assigned class does.
If you have single method to expose your approach is reasonable. Definetely going through JNI to C++/CLI and then .NET is much more reliable solution and easier to maintain than trying to handle such communication using COM objects.
Anyway for those who have more complex requirements like calling any method, passing ref/out arguments, calling generic methods, getting setting fields, subscribing .NET events handling exceptions, getting indexed properties etc..etc.. I think custom native wrapping will not work, at least not in rational time and cost.
If you have such requirements or just to be aware of the possbilities please have a look at third-party Java to .NET Bridges like:
Javonet
JNBridge
These two are more appropriate for this case as mentioned IKVM. Those Bridges let you use ANY .NET library directly in your JAVA code. They handle all the mentioned operations/scenarios and much more, including built-in data type translations and other mechanisms for known traps.
JNBridge is a lit bit more heavy and more expensive. However it has some dedicated plugins for enterprise systems like BizTalk. On the other hand Javonet is very light one jar-file solution half priced with very easy API. The other major difference is that Javonet works without proxy classes, so you do not have to generate any wrappers you just call .NET with reflection style whereas by JNBridge you can generate proxy classes that gives you strongly typed interface but it takes more time and effort. In my opinion it reduces flexibility a little bit as I like to have control over this what happens under the hood and with Javonet you can easily make your own strongly typed wrapped if you like.
I think this is not popular still but for single machine solution it is great approach that seamlessly covers the gap between .NET and JAVA with native performance. It is fraction of the percent of execution time taken by webservices and do not require any high level client-server infrastructures. In my tests it takes around 30% more time than executing particular code directly in .NET (it is very attractive).
It is good to hear you solve your case and I hope this post will help others with Java to .NET interop issues.
Below you can find sample code of Javonet using .NET Random class (it's important to notice that with third-party bridge you get access not only to your custom DLL but full .NET framework):
public void GenerateRandomNumber() throws JavonetException
{
NObject objRandom = Javonet.New("System.Random");
int value = objRandom.invoke("Next",10,20);
System.out.println(value);
}
Ended up getting JNI working correctly with C++ code, I was compiling the C++ as 32-bit, but I'm running a 64-bit JVM which was causing this extremely vague error.
I also ran into errors from .NET (Library wasn't in the GAC), so be sure to catch/report those correctly to Java, seems that uncaught exceptions cannot be wrapped in Java I believe.
I'll probably be posting this online as a resource soon, being as many JNI <-> .NET interop tutorials are way overcomplicated (usually adding what seems to be extremely unnecessary layers).
I do not know if this helps, but the open source project IKVM allows you to do the opposite, converting your Java application to .Net:
IKVM.NET is an implementation of Java
for Mono and the Microsoft .NET
Framework. It includes the following
components:
* A Java Virtual Machine implemented in .NET
* A .NET implementation of the Java class libraries
* Tools that enable Java and .NET interoperability
Your COM interop code looks almost right. However, you can't instantiate the coclass late-bound until you define the default interface on the class like this:
[Guid("3ECD46AE-E8F4-4B62-B9DC-DD7F6CB435E2"),
ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(typeof(ITest)),
ComSourceInterfaces(typeof(ITestEvents)),
ComVisible(true)]
public class Class1 : ITest

Categories