-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSampleProgram.cs
More file actions
155 lines (126 loc) · 4.25 KB
/
Copy pathSampleProgram.cs
File metadata and controls
155 lines (126 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using System.Runtime.InteropServices;
using System.Text;
using WolframLanguageRuntime;
/*
Documentation links for SDK functions used in this file:
wlr_sdk_StartRuntime - https://wolfr.am/1wl9JDTah
wlr_CreateExpressionPool - https://wolfr.am/1wl9MzvmX
wlr_Eval - https://wolfr.am/1wl9OeJOl
wlr_VariadicE - https://wolfr.am/1wl9PYmJe
wlr_ParseExpression - https://wolfr.am/1wl9SBSNH
wlr_ReleaseExpressionPool - https://wolfr.am/1wl9VbykU
wlr_StringData - https://wolfr.am/1wl9XfJgQ
wlr_String - https://wolfr.am/1wla043ht
wlr_Symbol - https://wolfr.am/1wla3FzQg
*/
unsafe class SampleProgram
{
// Start the kernel runtime. Evaluate and print sample expression.
static void Main()
{
if(!StartRuntime())
{
Console.Error.WriteLine("Failed to start kernel runtime.");
return;
}
Console.Error.WriteLine("Started kernel runtime.");
Console.WriteLine("WL Evaluation: 2+2 => " + EvaluateToOutputForm("2 + 2"));
}
// Start the kernel runtime. Return false on error.
static bool StartRuntime()
{
string layoutDirectory = @"C:\Program Files\Wolfram Research\Wolfram\14.3";
// Get unmanaged copy of string for use in SDK function
sbyte *layoutDirectoryPointer = (sbyte *) Marshal.StringToHGlobalAnsi(layoutDirectory);
WLR.wlr_error_type result =
WLR.Methods.wlr_sdk_StartRuntime(
WLR.wlr_application_type.WLR_EXECUTABLE,
WLR.wlr_version_type.WLR_VERSION_1,
WLR.wlr_license_type.WLR_LICENSE_OR_SIGNED_CODE_MODE,
layoutDirectoryPointer,
null
);
Marshal.FreeHGlobal((IntPtr) layoutDirectoryPointer);
return result == WLR.wlr_error_type.WLR_SUCCESS;
}
// Evaluate an input string, returning the result as a string in OutputForm. Return empty string on error.
static string EvaluateToOutputForm(string input)
{
WLR.Methods.wlr_CreateExpressionPool();
// Evaluate ToString[<expression parsed from input string>, OutputForm]
void *evaluatedExpression =
WLR.Methods.wlr_Eval(
WLR.Methods.wlr_VariadicE(
ExpressionFromString(ExpressionResultType.SYMBOL_RESULT, "ToString"),
2,
// This function accepts a variable number of arguments in __arglist(...). The previous argument is the number of
// arguments in the __arglist.
__arglist(
// Parse input string into unevaluated expression
WLR.Methods.wlr_ParseExpression(
// Get an expression corresponding to the input string
ExpressionFromString(ExpressionResultType.STRING_RESULT, input)
),
// Get an expression corresponding to the symbol OutputForm
ExpressionFromString(ExpressionResultType.SYMBOL_RESULT, "OutputForm")
)
)
);
// Get a C# string from evaluated expression, which will be our result
string result = StringFromExpression(evaluatedExpression);
// Release all of the expressions generated during this function
WLR.Methods.wlr_ReleaseExpressionPool();
return result;
}
// Get a C# string from a string expression
static string StringFromExpression(void *stringExpression)
{
sbyte *stringData;
int stringDataLength;
// Get unmanaged data corresponding to the string of a string expression
WLR.wlr_error_type error =
WLR.Methods.wlr_StringData(
stringExpression,
&stringData,
&stringDataLength
);
if(
(error != WLR.wlr_error_type.WLR_SUCCESS) ||
(stringDataLength == 0)
)
{
return "";
}
var memorySpan = new ReadOnlySpan<byte>(stringData, stringDataLength);
// Get C# string from unmanaged data allocated by wlr_StringData
string result = Encoding.UTF8.GetString(memorySpan);
// Free the unmanaged data allocated by wlr_StringData
WLR.Methods.wlr_Release(stringData);
return result;
}
// Get a string expression or symbol expression from C# string.
static void *ExpressionFromString(ExpressionResultType type, string input)
{
void *result;
fixed(byte *inputBytePointer = Encoding.UTF8.GetBytes(input))
{
sbyte *inputSignedBytePointer = (sbyte *) inputBytePointer;
if(type == ExpressionResultType.STRING_RESULT)
{
result = WLR.Methods.wlr_String(inputSignedBytePointer);
}
else
{
result = WLR.Methods.wlr_Symbol(inputSignedBytePointer);
}
}
return result;
}
// Enum for first argument to function ExpressionFromString.
enum ExpressionResultType
{
STRING_RESULT,
SYMBOL_RESULT
}
}