Re: Mathematica + NETLink + CodeDom- Example 2
- To: mathgroup at smc.vnet.net
- Subject: [mg45356] Re: [mg45304] Mathematica + NETLink + CodeDom- Example 2
- From: Todd Gayley <tgayley at wolfram.com>
- Date: Fri, 2 Jan 2004 04:23:45 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
At 11:22 PM 12/28/2003, ToolmakerSteve wrote: >(Follow on to [mg45085] NETLink - CREATING a new class? >I have submitted this to support@wolfram, >and explained that I hope it will be given to a programmer >who is working on NETLink - He's now back from vacation.... >so that the problems I encountered in mg45085 can be resolved, >and so that some example like this can be included in the NETLink >documentation, >in hopes that some other O-O .NET programmers can be enticed to use >Mathematica. >) Back in mg45085, the problem was: >"NET::nomethod: No public instance method named CompileAssemblyFromDom exists >for the .NET type Microsoft.CSharp.CSharpCodeGenerator." And the offending code was: > csharp = NETNew[ "Microsoft.CSharp.CSharpCodeProvider" ]; > cscompiler = csharp@CreateCompiler[]; > result = cscompiler@CompileAssemblyFromDom[ compParams, compUnit1 ]; The problem here is subtle, and it was a limitation in the first version of .NET/Link. The issue is that the actual class of the cscompiler object (Microsoft.CSharp.CSharpCodeGenerator) is private. Although this class implements the public ICodeCompiler interface, and therefore has a public method named CompileAssemblyFromDom, .NET/Link cannot invoke the method because the class is private. In a compiled .NET language program this is not a problem because the cscompiler object would be typed as the public ICodeCompiler interface, not its actual private runtime class type: // C# code. ICodeCompiler cscompiler = csharp.CreateCompiler(); result = cscompiler.CompileAssemblyFromDom(...); .NET/Link 1.1 includes a CastNETObject function that allows you to upcast the cscompiler object to the ICodeCompiler interface type. This would allow the method to be called just like in a C# program: cscompiler = CastNETObject[csharp@CreateCompiler[], "System.CodeDom.Compiler.ICodeCompiler"]; result = cscompiler@CompileAssemblyFromDom[ compParams, compUnit1 ]; The 1.1 version of .NET/Link ships with Mathematica 5.0.1 and will be available for general download in the very near future at www.wolfram.com/solutions/mathlink/netlink. In the meantime, you can work around the problem by manually using reflection to invoke the CompileAssemblyFromDom method defined in the ICodeCompiler interface: iccType = GetTypeObject[LoadNETType["System.CodeDom.Compiler.ICodeCompiler"]]; meth = iccType@GetMethod["CompileAssemblyFromDom"]; result = meth@Invoke[cscompiler, {compParams, compUnit1}]; There is another small issue in your old and new code--the problem you had with doing a BitOr merging of the MemberAttributes`Public and MemberAttributes`Static enum values. Normally this will work in .NET/Link, and your NetBitOr function is the correct way to do (flag1 | flag2) constructions in Mathematica (this is documented in the new .NET/Link 1.1 User Guide): NetBitOr[ net1_, net2_ ]:= BitOr[ NETObjectToExpression[ net1 ], NETObjectToExpression[ net2 ] ] The reason it doesn't work for the MemberAttributes enum is that for some reason this enum is not decorated with the [Flags] attribute, which is supposed to be applied to all enums that can have values bitor-ed together. It looks like a bug in the .NET Framework that the [Flags] attribute was left off the MemberAttributes enum. You can work around the problem by manually constructing an enum value of the right type by using the .NET Framework's Enum.ToObject() function: memberAttributesType = GetTypeObject[LoadNETType["System.CodeDom.MemberAttributes"]]; LoadNETType["System.Enum"]; attrs = Enum`ToObject[memberAttributesType, MakeNETObject[NetBitOr[MemberAttributes`Public, MemberAttributes`Static]]]; >Here is a more interesting notebook, >which creates a .NET assembly without >having to type all those "NETNew" expressions. > >It contains a package "NetCodeGen", >which is a translator from a simple structure in Mathematica, >which represents the assembly as code snippets within some structural >constructs. > >(By The Way, this is far more readable than the XML version of code that some >people are starting to work with in other environments.) Your approach is interesting, and I suggest you continue developing it, especially with an eye to allowing users to provide method implementations in the Mathematica language instead of only embedding strings of C# code in a Mathematica expression structure. This is quite similar to work that was in the development version of .NET/Link but pulled out before release because it was beyond the scope of a 1.0 release. Basically, it was decided that there was not sufficient time for the considerable design work required. Methods like DefineNETClass and NETMethod were once part of .NET/Link. Presumably, functionality like this will be introduced in a future release. Todd Gayley Wolfram Research
- Follow-Ups:
- Re: Re: Mathematica + NETLink + CodeDom-Example 2
- From: Todd Gayley <tgayley@wolfram.com>
- Re: Mathematica + NETLink + CodeDom- Example 2
- From: "murphee (Werner Schuster)" <werner.schuster@netway.at>
- Re: Re: Mathematica + NETLink + CodeDom-Example 2