Skip to content

Commit 153e832

Browse files
committed
Implemented InMemory assembly loading.
Fixed MathAssembly with loading from byte array without app domains (memory leaks are possible in this case).
1 parent a8cc666 commit 153e832

File tree

4 files changed

+52
-43
lines changed

4 files changed

+52
-43
lines changed

MathExpressions.NET.GUI/frmMain.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ private void btnSave_Click(object sender, EventArgs e)
9999
if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
100100
{
101101
if (Assembly != null)
102-
Assembly.Finalize(Path.GetDirectoryName(saveFileDialog1.FileName), Path.GetFileName(saveFileDialog1.FileName));
102+
Assembly.SaveToFile(Path.GetDirectoryName(saveFileDialog1.FileName), Path.GetFileName(saveFileDialog1.FileName));
103103
}
104104
}
105105

MathExpressions.NET.Tests/MathFuncCompilationTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ public void Init()
1818
Helper.InitDefaultDerivatives();
1919
}
2020

21+
[Test]
22+
public void MemoryConsumption()
23+
{
24+
for (int i = 0; i < 10000000; i++)
25+
{
26+
using (var mathAssembly = new MathAssembly("x ^ 2", "x"))
27+
{
28+
Assert.AreEqual(25, mathAssembly.Func(5));
29+
}
30+
}
31+
}
32+
2133
[Test]
2234
public void CompileFunc()
2335
{

MathExpressions.NET/MathAssembly.cs

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ namespace MathExpressionsNET
1010
[Serializable]
1111
public class MathAssembly : IDisposable
1212
{
13-
private static string _chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
14-
private static Random _rand = new Random();
15-
16-
private AppDomain _domain;
17-
private string _fileName = "MathFuncLib.dll";
1813
private object _mathFuncObj;
1914

2015
public MethodInfo FuncMethodInfo
@@ -42,42 +37,22 @@ public double FuncDerivative(params object[] x)
4237
public MathAssembly(string expression, string variable)
4338
{
4439
var mathAssembly = new MathFuncAssemblyCecil();
45-
_fileName = "MathFuncLib" + "_" + GenerateRandomString(6) + ".dll";
46-
mathAssembly.CompileFuncAndDerivative(expression, variable, "", _fileName);
47-
_domain = AppDomain.CreateDomain("MathFuncDomain");
48-
_mathFuncObj = _domain.CreateInstanceFromAndUnwrap(_fileName, mathAssembly.NamespaceName + "." + mathAssembly.ClassName);
40+
var fileName = "MathFuncLib" + "_" + Guid.NewGuid().ToString() + ".dll";
41+
var assemblyBytes = mathAssembly.CompileFuncAndDerivativeInMemory(expression, variable, fileName);
42+
var assembly = Assembly.Load(assemblyBytes);
43+
_mathFuncObj = assembly.CreateInstance(mathAssembly.NamespaceName + "." + mathAssembly.ClassName);
4944
var mathFuncObjType = _mathFuncObj.GetType();
5045
FuncMethodInfo = mathFuncObjType.GetMethod(mathAssembly.FuncName);
5146
FuncDerivativeMethodInfo = mathFuncObjType.GetMethod(mathAssembly.FuncDerivativeName);
5247
}
5348

5449
public void Dispose()
5550
{
56-
if (_domain != null)
57-
AppDomain.Unload(_domain);
58-
File.Delete(_fileName);
59-
}
60-
61-
void _domain_DomainUnload(object sender, EventArgs e)
62-
{
63-
throw new NotImplementedException();
6451
}
6552

6653
~MathAssembly()
6754
{
6855
Dispose();
6956
}
70-
71-
public static string GenerateRandomString(int length)
72-
{
73-
byte[] bytes = new byte[length];
74-
var random = new Random();
75-
random.NextBytes(bytes);
76-
StringBuilder result = new StringBuilder(length);
77-
foreach (var b in bytes)
78-
result.Append(_chars[b % _chars.Length]);
79-
80-
return result.ToString();
81-
}
8257
}
8358
}

MathExpressions.NET/MathFuncAssemblyCecil.cs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,23 @@ public MathFuncAssemblyCecil(string namespaceName = "MathFuncLib", string classN
4747
ClassName = className;
4848
}
4949

50-
public void CompileFuncAndDerivative(string expression, string variable, string fileName = "")
50+
public void CompileFuncAndDerivativeToFile(string expression, string variable, string fileName = "")
5151
{
52-
CompileFuncAndDerivative(expression, variable, Path.GetDirectoryName(fileName), Path.GetFileName(fileName));
52+
CompileFuncAndDerivativeToFile(expression, variable, Path.GetDirectoryName(fileName), Path.GetFileName(fileName));
5353
}
5454

55-
public void CompileFuncAndDerivative(string expression, string variable, string filePath = "", string name = "")
55+
public void CompileFuncAndDerivativeToFile(string expression, string variable, string filePath = "", string name = "")
5656
{
57-
var func = new MathFunc(expression, variable, true, true);
58-
var funcDer = new MathFunc(expression, variable, true, false).GetDerivative().GetPrecompilied();
59-
60-
Init(name);
61-
62-
func.Compile(this, FuncName);
63-
funcDer.Compile(this, FuncDerivativeName);
64-
65-
Finalize(filePath, name);
57+
CompileFuncAndDerivative(expression, variable, name);
58+
SaveToFile(filePath, name);
6659
}
6760

61+
public byte[] CompileFuncAndDerivativeInMemory(string expression, string variable, string name = "")
62+
{
63+
CompileFuncAndDerivative(expression, variable, name);
64+
return SaveToBytes();
65+
}
66+
6867
public void Init(string fileName = "MathFuncLib.dll")
6968
{
7069
var name = new AssemblyNameDefinition(Path.GetFileNameWithoutExtension(fileName), new Version(1, 0, 0, 0));
@@ -86,12 +85,35 @@ public void Init(string fileName = "MathFuncLib.dll")
8685
Class.Methods.Add(method);
8786
}
8887

89-
public void Finalize(string path = "", string fileName = "")
88+
public void SaveToFile(string path = "", string fileName = "")
9089
{
9190
Assembly.MainModule.Types.Add(Class);
9291
Assembly.Write(Path.Combine(path, string.IsNullOrEmpty(fileName) ? NamespaceName + ".dll" : fileName));
9392
}
9493

94+
public byte[] SaveToBytes()
95+
{
96+
Assembly.MainModule.Types.Add(Class);
97+
byte[] result = null;
98+
using (var stream = new MemoryStream())
99+
{
100+
Assembly.Write(stream);
101+
result = stream.ToArray();
102+
}
103+
return result;
104+
}
105+
106+
private void CompileFuncAndDerivative(string expression, string variable, string name = "")
107+
{
108+
var func = new MathFunc(expression, variable, true, true);
109+
var funcDer = new MathFunc(expression, variable, true, false).GetDerivative().GetPrecompilied();
110+
111+
Init(name);
112+
113+
func.Compile(this, FuncName);
114+
funcDer.Compile(this, FuncDerivativeName);
115+
}
116+
95117
private void ImportMath(AssemblyDefinition assembly)
96118
{
97119
TypesReferences = new Dictionary<KnownFuncType, MethodReference>();

0 commit comments

Comments
 (0)