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:)
Related
I am looking to replace certain reflection-based parts of our code with ones that perform better using dynamic runtime compilation. Looking around I saw that both Mono and Microsoft have separate Compiler-as-a-Service solutions: Mono.CSharp and Microsoft.CSharp.
With the risk of asking an opinion-based question, I'm wondering how these two compare?
As far as I can tell from a very superficial initial investigation, they both generally provide CAAS capabilities. I was able to compile a "Hello World" class using Microsoft.CSharp and execute it. And although I didn't do the same thing with the Mono one yet, I'm assuming it could do the same.
Does anyone have any experience with either or both and can comment on the issue?
Edit: I am not asking about a comparison of Mono's C# and Microsoft's C# - we are already familiar with and using both. The question is specifically about the two CAAS (Compiler-as-a-Service) solutions.
CAAS isn't (yet anyway) a standard part of the .NET runtime, i.e there is no System.Compile namespace yet. The two solutions Mono.CSharp and Microsoft.CSharp are separate non-standard CAAS solutions for C#. Their interfaces are very different and hence the question.
Mono's compiler service
Microsoft's compiler service
Edit #2: Completely forgot about Roslyn (thanks to #Lex Li)
Microsoft.CSharp as it's now (.net 4.5) is API used by C# compiler to emit bindings for C# dynamic expressions. Therefore it's C# compiler but very limited. The same API (dll) is implemented by both .NET and Mono so you can compile on .NET and run on Mono and vice-versa.
Mono.CSharp is evaluator style API to Mono C# compiler. It allows you to compile any C# text-like code (expressions, statement, type declarations, etc) and execute it. It relies on System.Reflection and System.Reflection.Emit heavily.
Neither of these have any relation to CodeDom.
Well I have now compared Mono.CSharp with Microsoft.CSharp and the result is that Mono's version performs badly in comparison.
I compiled the following code with both dynamic compilers:
using System;
using CompilerServiceTest;
public class LalaDynamicImpl : ILala
{
private static int _counter;
public void DoLala()
{
_counter++;
}
}
The main program looks something along the lines of:
public interface ILala
{
void DoLala();
}
public class LalaStaticImpl : ILala
{
private static int _counter;
public void DoLala()
{
_counter++;
}
}
public class Program
{
public static void Main(string[] args)
{
Message("Compiling dynamic lala...");
var lala = BuildDynamicLala();
Message("Testing dynamic lala...");
Test(lala);
Message("Sleeping for 1s...");
GC.Collect();
Thread.Sleep(1000);
Message("Testing static lala...");
Test(new LalaStaticImpl());
}
private static void Test(ILala lala)
{
var watch = Stopwatch.StartNew();
for (var i = 0; i < 1000000000; i++)
lala.DoLala();
Console.WriteLine(watch.Elapsed);
}
}
On my machine the results are:
Statically compiled class: 1.9s
Dynamically compiled class compiled with Microsoft.CSharp: 1.9s
Dynamically compiled class compiled with Mono.CSharp: 10s
The results correspond with what the Mono team mentions here and what Marek Safar mentions in his answser - the Microsoft.CSharp compiler service is a wrapper for the actual compiler and the code is compiled and optimized in the same way as normal code. The Mono.Csharp compiler service is separate from the Mono compiler and is more of an "eval" machine. It does not optimize the code in the same way as the standard compiler.
Basically it appears that the Mono compiler service isn't really intended for performance-critical scenarios, but for rich features, learning, testing, etc.
Tested on a Windows 7 64bit machine with .NET 4.0 (VS 2010) and Mono 3.2.3.
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
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
I am attempting to write a DLL using the C# .NET Framework 2.0. Everything compiles okay, but when I try to access the DLL from my application, it fails when attempting to get the procedure address. So, I oped the DLL in Dependency Walker, and all of my public functions are missing!
My DLL, so far, is fairly straightforward:
namespace MyDll_Namespace
{
public class MyDllClass
{
public static int Func1( /* params */ ) { /* ... */ }
public static int Func2( /* params */ ) { /* ... */ }
public static int Func3( /* params */ ) { /* ... */ }
public static int Func4( /* params */ ) { /* ... */ }
}
}
There's not much else, just a few constants and delegates defined inside the class, as well as outside the class in the namespace. Any thoughts or suggestions would be much appreciated. Thanks.
Dependency walker is for win32 DLLs (which is native code), not .NET assemblies (which is managed code). It won't find methods in an arbitrary class (even if they are static). If you need to call managed code from native code, there are ways of doing that, but it's not pretty.
If you want to use your dll from managed code, it's a lot easier. Check out System.Assembly and Activator.
An example of this:
var assembly = Assembly.LoadFile(#"\path\to\your.dll");
var mydllclass_type = assembly.GetType("MyDllClass");
var instance = Activator.CreateInstance(mydllclass_type);
The instance will be an object. To call the methods, you need to use reflection, because the interface is not known at compile-time.
If you are creating a plugin system, the best way is to have a common interface or abstract base for all plugins, and have that referenced by your program. Those third parties who implement a plugin, will also reference this contract. In this case, the last line changes a bit:
var instance = (IMyDllClass)Activator.CreateInstance(mydllclass_type);
Now you can use the methods like in a regularly constructed object.
Part of the problem here is that dependency walker is a tool for native applications. It doesn't understand managed code and hence won't display any of the managed types + methods that you've defined.
I'm confused by this line in your question
when I try to access the DLL from my application, it fails when attempting to get the procedure address
This sounds a bit like an error I would see in a native application, not a managed one. Are you trying to access the C# code from a native application? If so this can only be done via COM magic and not via direct calling. Can you explain in more detail what is going on here?
Try .net Reflector to see exactly what's inside your built DLL (in order to make sure everything is the way it is supposed to).
Also make sure you're in release mode while building your DLL before referencing it... I don't know if it's going to change anything, but it worths the try =)
You need to add a reference to your dll and the runtime will automatically allow you to call your function. Here is a little tutorial on writing a .net class library.
I decided to write my DLLs in C++. However, here is a bunch of useful information I found for using managed code from unmanaged code:
Is it possible to use a DLL created using C# in an unmanaged VC++ application?
How do I call C++/CLI (.NET) DLLs from standard, unmanaged non-.NET applications?
Using managed code in an unmanaged application
Using Managed Components from Unmanaged Code
An Overview of Managed/Unmanaged Code Interoperability
Unmanaged Exports
Calling Managed .NET C# COM Objects from Unmanaged C++ Code
All-In-One Code Framework
CLR Hosting APIs
How To: Migrate to /clr
How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005
i need to bind C++ dll to my C# WinCE program. (scanner dll)
how i can do it ?
thank's in advance
You need to use Interop to call into unmanaged code.
using System.Runtime.InteropServices; // DllImport
public class Win32 {
[DllImport("User32.Dll")]
public static extern void SetWindowText(int h, String s);
}
Here is an article that discusses the topic in detail (also where the code is sourced from).
http://msdn.microsoft.com/en-us/magazine/cc301501.aspx
An alternative to InterOp is to write a C++ DLL using CLR extensions which acts as a wrapper to the traditional C++ DLL. This gives you a chance to handle unusual types, e.g. custom structures or classes, if Marshaling isn't going to work. (According to MSDN you can extend the Marshaling support (http://msdn.microsoft.com/en-us/library/bb531313.aspx) but I haven't tried this personally, and depending on what you're doing it might be a lot of work).
For example if you want to access a DLL which exports a class, you can have a wrapper DLL which owns an instance of the C++ class and defines a .NET class which maps onto the C++ class. For example, here's a snippet from a C++/CLR DLL which we use to make one of our old C++ DLLs available in .NET:
// This is the constructor for the CLR (managed) object
FileInf::FileInf()
{
// Create the C++ (unmanaged) object
m_pFileInf = gcnew DILib::FileInf();
}
// This is a managed interface which replicates the old
// unmanaged functionality
bool FileInf::IsDirectory()
{
return m_pFileInf->IsDirectory();
}
I'd say if InterOp works then stick with it, but I'm not sure if it's the best way to solve every C++ / .NET interfacing problem, and this is an alternative.