I wanted to see how difficult it would be to use the OpenMaple API from a C# program. It turns out that it is pretty easy to access C .dlls from C#. I was able to reproduce a commandline equivalent (minus the command history and editing features).
The source code can be found here: openmaple.cs
Here is a sample run:
|\^/| OpenMaple (Example Program)
._|\| |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc. 2009
\OPENMAPLE/ All rights reserved. Maple and OpenMaple are trademarks of
<____ ____> Waterloo Maple Inc.
| Type ? for help.
> plot(sin); #shows up in a separate window
cputime=0.156; memory used=1040kB alloc=911kB
Initializing Java runtime environment.
cputime=0.171; memory used=1107kB alloc=927kB
This example defines a MapleEngine class with methods StartMaple, StopMaple, EvalMapleStatment, and IsMapleStop. These methods are just direct calls to the C OpenMaple API. Once you have the ability to make a connection to Maple and evaluate a statement you really have access to the full power of Maple's computation engine.
More methods can easily be added as long as you keep the following in mind.
- Strings in C# are all unicode characters. To talk to a C .dll you need to convert these characters to ASCII. When passing string arguments to an API function use Encoding.ASCII.GetBytes(s) to turn your string into an ascii byte array first. When getting strings back, I chose to declare them as IntPtr (rather than byte), and use Marshal.PtrToStringAnsi(x) to turn the char* pointer into a C# string.
- The OpenMaple API makes use of pointer types (ALGEB), and machine word size integers (M_INT). Both of these should be declared as IntPtr in order to keep your code compatable between 64-bit and 32-bit operating systems. If x is declared as an IntPtr (rather than long or M_INT), you can use the method x.ToInt32() or x.ToInt64() to get the integer value. ALGEB pointers can generally be left as is (black-boxes) and passed around only to other API functions.
The only tricky business that isn't resolved in this example is the ability to pass multiple commandline flags in via the argv parameter to StartMaple. Maybe someone can suggest a good way to pass the equivalent of char *argv out from a C# program? This isn't a big deal though as most Maple options can be set via commands after the engine is initialized.