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.
Related
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!";
}
}
Is there a way of intercepting some method calls without making any code changes around the method itself?
I don't need to inject any custom behaviour at runtime, only add custom performance logging to an existing project.
You want Aspect Oriented Programming.
There are 4 main flavours of AOP
Runtime RealProxy based AOP
Runtime subclass/virtual method AOP
Post Compile IL weave AOP
Precompile source code AOP
The above are ordered in order of speed of execution (slowest to fastest). Note the last two "should" be the same speed. However I expect the compiler to produce better IL than a Post Compile IL weave.
The first camp usually includes IOC containers, since they lend themselves fairly well to this pattern, including and not limited to
Unity
Spring.NET
Castle.Windsor
Postsharp Express
The second camp, is pretty rare, and the only project that I can think of off the top of my head is Entity Framework (which uses it for Lazy loading, however it isn't extensible, and cannot be customised).
The third camp is pretty sparce also, since this technique is extremely complicated and difficult. This works by editing the dll assembly AFTER you have compiled, to add the extra code you want.
Postsharp Pro
Mono.Cecil
Fody (a mono.cecil wrapper)
The final camp is relatively new. So new in fact, the only real entry is the experimental MS Roslyn. This is actually a C# compiler. So...yeah...its pretty magic.
Now, if you are having real huge performance issues with performance critical code, I would suggest using Fody. What is awesome about this, is that it is free (unlike Postsharp Pro), it uses nuget and there is already a performance tool in Fody.MethodTimer.
I have successfully used Castle DynamicProxy for that. It's more lightweight than a full fledged AOP framework, and can be used without an IoC container.
You could take a look at Aspect Oriented Programming, and see if it's a solution for your situation.
For instance:
http://docs.castleproject.org/Default.aspx?Page=Introduction-to-AOP-With-Castle&NS=Windsor&AspxAutoDetectCookieSupport=1
http://fgheysels.blogspot.be/2006/11/aspect-oriented-programming-in-net.html
You can use any AOP Frameworks, like to Spring .NET or Unity, to intercept calls, before or after the method execute.
Thus, you dont need to change your method code.
What you are looking for is Fody: https://github.com/fody
Its open source, stable and has lots of plugins for different AOP use cases.
I am using it in a huge commercial application, and it is working very well.
Installation and configuration is super easy and done within some minutes via nuget.
Some example plugins are:
PropertyChanged: (Injects INotifyPropertyChanged code into properties at compile time)
Anotar (Simplifies logging through a static class and some IL manipulation)
Method Timer (Injects some very basic method timing code)
... and many more!
Requirements, examples and docs can be found on fodys github pages.
Using PostSharp
[Serializable]
public class LogPerformance : OnMethodBoundaryAspect
{
[NonSerialized]
Stopwatch _stopWatch;
public override void OnEntry(MethodExecutionArgs args)
{
_stopWatch = Stopwatch.StartNew();
base.OnEntry(args);
}
public override void OnExit(PostSharp.Aspects.MethodExecutionArgs args)
{
Console.WriteLine(string.Format("[{0}] took {1} ms to execute",
new StackTrace().GetFrame(1).GetMethod().Name,
_StopWatch.ElapsedMilliseconds));
base.OnExit(args);
}
}
Use the aspect like so on a function:
[LogPerformance]
static void LongRunningCalc()
{
//Your Code goes here
}
Simplified from : http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS
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:)
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