Skip to content

Commit e3f9aa2

Browse files
committed
Added basic Core tests via new assets
1 parent 2a77214 commit e3f9aa2

16 files changed

+750
-13
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Specific
22

33
/src/MetadataCore/DllExport.xml
4+
launchSettings.json
45

56
## Ignore Visual Studio temporary files, build results, and
67
## files generated by popular Visual Studio add-ons.
@@ -246,4 +247,4 @@ ModelManifest.xml
246247
.paket/paket.exe
247248

248249
# FAKE - F# Make
249-
.fake/
250+
.fake/

.vssbe

+22
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,28 @@
11541154
"#[IO scall(\"cmd\", \"/C mklink /J $(dbgPkgDir)DllExport.$(pVerRel) $(odir.Replace('/', '\\'))\")]"
11551155
]
11561156
}
1157+
},
1158+
{
1159+
"Enabled": true,
1160+
"Name": "Assets",
1161+
"IgnoreIfBuildFailed": true,
1162+
"Mode": {
1163+
"$type": "net.r_eg.vsSBE.Events.ModeScript, vsSolutionBuildEvent",
1164+
"Type": "Script",
1165+
"Command__": [
1166+
"#[try",
1167+
"{",
1168+
" #[IO delete.directory(\"$(RootAssetsDir)\", true)]",
1169+
"} catch{ F-53, SobaScript }]",
1170+
"",
1171+
"#[IO copy.directory(\"\", \"$(RootAssetsDir)\", true)]",
1172+
"#[IO scall(\"cmd\", \"/C mklink /J $(RootAssetsDir)\\DllExport $(odir.Replace('/', '\\'))\")]",
1173+
"",
1174+
"",
1175+
"#[File scall(\"DllExport.bat\", \"-packages $(RootAssetsDir) -dxp-version actual -action Restore >nul\", 60)]",
1176+
"#[File scall(\".tools\\hMSBuild.bat\", \"assets.sln ~x ~c $(Configuration) ~p \\\"$(Platform)\\\" /p:RootAssetsDir=$(RootAssetsDir) >nul\", 200)]"
1177+
]
1178+
}
11571179
}
11581180
],
11591181
"SlnOpened": [

DllExport.bat

+262
Large diffs are not rendered by default.

DllExport.sln

+27-7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
44
VisualStudioVersion = 17.11.35312.102
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\DllExport\Core\Core.csproj", "{AC6947C6-0637-429A-A5F1-54447A494E6D}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\DllExport\Core\Core.csproj", "{AC6947C6-0637-429A-A5F1-54447A494E6D}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaFx", "src\DllExport\MetaFx\MetaFx.csproj", "{D620BC4A-50CD-48DF-8C6E-B79555260EA0}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetaFx", "src\DllExport\MetaFx\MetaFx.csproj", "{D620BC4A-50CD-48DF-8C6E-B79555260EA0}"
99
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Activator", "src\DllExport\Activator\Activator.csproj", "{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}"
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Activator", "src\DllExport\Activator\Activator.csproj", "{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}"
1111
EndProject
1212
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{E623294B-0FEA-4FA2-BA15-2750FE503F50}"
1313
ProjectSection(SolutionItems) = preProject
@@ -34,13 +34,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".tools", ".tools", "{44F550
3434
.tools\packages.config = .tools\packages.config
3535
EndProjectSection
3636
EndProject
37-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSBin", "src\DllExport\NSBin\NSBin.csproj", "{311706A5-5ED2-4006-B794-055009D8A256}"
37+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NSBin", "src\DllExport\NSBin\NSBin.csproj", "{311706A5-5ED2-4006-B794-055009D8A256}"
3838
EndProject
39-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSBinTest", "src\DllExport\NSBinTest\NSBinTest.csproj", "{3CFD9EB8-69BC-4B41-9ABA-9C1850BE324A}"
39+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NSBinTest", "src\DllExport\NSBinTest\NSBinTest.csproj", "{3CFD9EB8-69BC-4B41-9ABA-9C1850BE324A}"
4040
EndProject
41-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wizard", "src\DllExport\Wizard\Wizard.csproj", "{D10CF407-4483-4657-9FEA-BDB467391F3A}"
41+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wizard", "src\DllExport\Wizard\Wizard.csproj", "{D10CF407-4483-4657-9FEA-BDB467391F3A}"
4242
EndProject
43-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeViewer", "src\DllExport\PeViewer\PeViewer.csproj", "{BE8C8005-A6C6-41D0-9DB0-6B4B7BD1077F}"
43+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PeViewer", "src\DllExport\PeViewer\PeViewer.csproj", "{BE8C8005-A6C6-41D0-9DB0-6B4B7BD1077F}"
4444
EndProject
4545
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MvsSln", "src\MvsSln\MvsSln\MvsSln.csproj", "{F905DFB2-2E67-4FF7-9001-924F6F2D645D}"
4646
EndProject
@@ -107,6 +107,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{179AF057
107107
src\hMSBuild\GetNuTool\tests\_run.bat = src\hMSBuild\GetNuTool\tests\_run.bat
108108
EndProjectSection
109109
EndProject
110+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitedTest", "src\DllExport\UnitedTest\UnitedTest.csproj", "{0B356E3D-F2D6-485B-A8D9-3B78ED978550}"
111+
ProjectSection(ProjectDependencies) = postProject
112+
{0F0E1861-4EC7-4125-B16A-EE95FA80FA0F} = {0F0E1861-4EC7-4125-B16A-EE95FA80FA0F}
113+
{311706A5-5ED2-4006-B794-055009D8A256} = {311706A5-5ED2-4006-B794-055009D8A256}
114+
{3CFD9EB8-69BC-4B41-9ABA-9C1850BE324A} = {3CFD9EB8-69BC-4B41-9ABA-9C1850BE324A}
115+
{9C75E9C4-5D81-4704-ADD1-F4B42B6267C8} = {9C75E9C4-5D81-4704-ADD1-F4B42B6267C8}
116+
{AC6947C6-0637-429A-A5F1-54447A494E6D} = {AC6947C6-0637-429A-A5F1-54447A494E6D}
117+
{BE8C8005-A6C6-41D0-9DB0-6B4B7BD1077F} = {BE8C8005-A6C6-41D0-9DB0-6B4B7BD1077F}
118+
{D10CF407-4483-4657-9FEA-BDB467391F3A} = {D10CF407-4483-4657-9FEA-BDB467391F3A}
119+
{D620BC4A-50CD-48DF-8C6E-B79555260EA0} = {D620BC4A-50CD-48DF-8C6E-B79555260EA0}
120+
{EC0CA220-39EC-41E5-B9D6-88D8F860F979} = {EC0CA220-39EC-41E5-B9D6-88D8F860F979}
121+
{F905DFB2-2E67-4FF7-9001-924F6F2D645D} = {F905DFB2-2E67-4FF7-9001-924F6F2D645D}
122+
EndProjectSection
123+
EndProject
110124
Global
111125
GlobalSection(SolutionConfigurationPlatforms) = preSolution
112126
Debug|Any CPU = Debug|Any CPU
@@ -174,6 +188,12 @@ Global
174188
{0F0E1861-4EC7-4125-B16A-EE95FA80FA0F}.PublicRelease|Any CPU.Build.0 = Release|Any CPU
175189
{0F0E1861-4EC7-4125-B16A-EE95FA80FA0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
176190
{0F0E1861-4EC7-4125-B16A-EE95FA80FA0F}.Release|Any CPU.Build.0 = Release|Any CPU
191+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
192+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.Debug|Any CPU.Build.0 = Debug|Any CPU
193+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.PublicRelease|Any CPU.ActiveCfg = Release|Any CPU
194+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.PublicRelease|Any CPU.Build.0 = Release|Any CPU
195+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.Release|Any CPU.ActiveCfg = Release|Any CPU
196+
{0B356E3D-F2D6-485B-A8D9-3B78ED978550}.Release|Any CPU.Build.0 = Release|Any CPU
177197
EndGlobalSection
178198
GlobalSection(SolutionProperties) = preSolution
179199
HideSolutionNode = FALSE

Readme.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public static int entrypoint(IntPtr L)
4848

4949
For working with **unmanaged** memory including native or binary data from the heap and binding between .NET and unmanaged native C/C++ etc, try [Conari](https://github.com/3F/Conari) (Wiki. [**Quick-start**](https://github.com/3F/Conari/wiki/Quick-start))
5050

51+
[`[⏯]`](.\src\DllExport\assets\NetfxAsset\Basic.cs)
52+
5153
```csharp
5254
[DllExport] // DllExportModifiedClassLibrary.dll
5355
public static IntPtr callme(TCharPtr str, IntPtr structure)
@@ -62,6 +64,9 @@ public static IntPtr callme(TCharPtr str, IntPtr structure)
6264
return new NativeArray<int>(-1, v.x, 1, v.y);
6365
}
6466
```
67+
68+
[`[⏯]`](.\src\DllExport\UnitedTest\NetfxAssetBasicTest.cs)
69+
6570
```csharp
6671
... // host side via C/C++, Java, Rust, Python, ... or even same dotnet C#
6772
using NativeString<TCharPtr> ns = new("Hello world!");
@@ -75,7 +80,7 @@ using NativeArray<int> nr = new(4, ptr); // (nstruct.Data.x == 8) != (nr[1] == 7
7580

7681
*.NET DllExport* supports both Library (**.dll**) and Executable (**.exe**) PE modules.
7782

78-
Find demo project here: https://github.com/3F/Examples/tree/master/DllExport/BasicExport
83+
`[⏯]` See also demo project here: https://github.com/3F/Examples/tree/master/DllExport/BasicExport
7984

8085
## How does it work
8186

assets.sln

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.11.35327.3
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DllExport", "DllExport", "{7EFE776C-2D5C-487B-81F3-14D53D6F7099}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetfxAsset", "src\DllExport\assets\NetfxAsset\NetfxAsset.csproj", "{4D13A153-4DE3-4342-B447-F2DB081B2981}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{4D13A153-4DE3-4342-B447-F2DB081B2981}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{4D13A153-4DE3-4342-B447-F2DB081B2981}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{4D13A153-4DE3-4342-B447-F2DB081B2981}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{4D13A153-4DE3-4342-B447-F2DB081B2981}.Release|Any CPU.Build.0 = Release|Any CPU
20+
EndGlobalSection
21+
GlobalSection(SolutionProperties) = preSolution
22+
HideSolutionNode = FALSE
23+
EndGlobalSection
24+
GlobalSection(NestedProjects) = preSolution
25+
{4D13A153-4DE3-4342-B447-F2DB081B2981} = {7EFE776C-2D5C-487B-81F3-14D53D6F7099}
26+
EndGlobalSection
27+
GlobalSection(ExtensibilityGlobals) = postSolution
28+
SolutionGuid = {1ED17F28-E550-4B00-8DF9-BD43241EEA55}
29+
EndGlobalSection
30+
EndGlobal

assets.vssbe

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Header": {
3+
"_": [
4+
" This file for vsSolutionBuildEvent ",
5+
" https://github.com/3F/vsSolutionBuildEvent "
6+
],
7+
"Compatibility": "0.12.4"
8+
}
9+
}

build.bat

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
set reltype=%~1
1717
if not defined reltype set reltype=Release
1818

19-
call .tools\gnt & call packages\vsSolutionBuildEvent\cim.cmd ~x ~c %reltype% || goto err
19+
call .tools\gnt & call packages\vsSolutionBuildEvent\cim.cmd ~x ~c %reltype% DllExport.sln || goto err
2020
set "frel=%reltype:Public=%"
2121

2222
setlocal enableDelayedExpansion

src/DllExport/UnitedTest/Assets.cs

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*!
2+
* Copyright (c) Denis Kuzmin <[email protected]> github/3F
3+
* Copyright (c) DllExport contributors https://github.com/3F/DllExport/graphs/contributors
4+
* Licensed under the MIT License (MIT).
5+
* See accompanying LICENSE.txt file or visit https://github.com/3F/DllExport
6+
*/
7+
8+
using System;
9+
using System.IO;
10+
using static net.r_eg.Conari.Static.Members;
11+
12+
namespace net.r_eg.DllExport.UnitedTest
13+
{
14+
using PeMagic = Conari.PE.WinNT.Magic;
15+
16+
internal sealed class Assets
17+
{
18+
const string X64 = "x64";
19+
const string X86 = "x86";
20+
21+
internal const string PRJ_NETFX = "NetfxAsset";
22+
23+
internal const string ROOT = @"bin\assets\";
24+
25+
internal const string PKG = @"bin\assets\DllExport\";
26+
27+
internal static PeMagic MagicAtThis => Is64bit ? PeMagic.PE64 : PeMagic.PE32;
28+
29+
/// <summary>
30+
/// Path to bin at NetfxAsset project
31+
/// </summary>
32+
internal static string PrjNetfxBin => GetPathToPrj(PRJ_NETFX);
33+
34+
/// <summary>
35+
/// x86 modified module at NetfxAsset project
36+
/// </summary>
37+
internal static string PrjNetfxX86 => GetDllPath(PRJ_NETFX, X86);
38+
39+
/// <summary>
40+
/// x64 modified module at NetfxAsset project
41+
/// </summary>
42+
internal static string PrjNetfxX64 => GetDllPath(PRJ_NETFX, X64);
43+
44+
/// <summary>
45+
/// original or modified (x86/x64) at NetfxAsset project
46+
/// </summary>
47+
internal static string PrjNetfx => GetPathToPrj(PRJ_NETFX);
48+
49+
/// <summary>
50+
/// <see cref="PrjNetfxX64"/> or <see cref="PrjNetfxX86"/> depending on env at runtime
51+
/// </summary>
52+
internal static string PrjNetfxRuntime => Is64bit ? PrjNetfxX64 : PrjNetfxX86;
53+
54+
internal static string GetDllPath(string project) => GetDllPath(project, string.Empty);
55+
56+
internal static string GetDllPath(string project, string arch)
57+
{
58+
return Path.Combine(GetPathToPrj(project), arch, $"{project}.dll");
59+
}
60+
61+
internal static string GetPathToPrj(string name) => GetPathTo("prj", name);
62+
63+
internal static string GetPathToObj(string name) => GetPathTo("obj", name);
64+
65+
internal static string GetPathTo(string baseName, string subname)
66+
{
67+
return Path.GetFullPath(Path.Combine
68+
(
69+
AppDomain.CurrentDomain.BaseDirectory,
70+
@"..\..\..\..", // common.props: bin\prj\$(MSBuildProjectName)\$(Configuration)
71+
72+
ROOT,
73+
#if DEBUG
74+
"Debug",
75+
#else
76+
"Release",
77+
#endif
78+
baseName, subname
79+
))
80+
+ Path.DirectorySeparatorChar;
81+
}
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*!
2+
* Copyright (c) Denis Kuzmin <[email protected]> github/3F
3+
* Copyright (c) DllExport contributors https://github.com/3F/DllExport/graphs/contributors
4+
* Licensed under the MIT License (MIT).
5+
* See accompanying LICENSE.txt file or visit https://github.com/3F/DllExport
6+
*/
7+
8+
using System;
9+
using System.Linq;
10+
using net.r_eg.Conari;
11+
using net.r_eg.Conari.PE;
12+
using net.r_eg.Conari.Types;
13+
using Xunit;
14+
15+
namespace net.r_eg.DllExport.UnitedTest
16+
{
17+
public class NetfxAssetBasicTest
18+
{
19+
[Fact]
20+
public void AddTest1()
21+
{
22+
using dynamic l = new ConariX(Assets.PrjNetfxRuntime);
23+
int x = l.add<int>(5, 7);
24+
25+
Assert.Equal(12, x);
26+
27+
IPE pe = ((IConari)l).PE;
28+
Assert.Equal(pe.Magic, Assets.MagicAtThis);
29+
30+
Assert.NotEmpty(pe.ExportedProcNames);
31+
Assert.NotNull(pe.ExportedProcNames.FirstOrDefault(s => s == "add"));
32+
}
33+
34+
[Fact]
35+
public void CallmeTest1()
36+
{
37+
TCharPtr.Unicode = true;
38+
using NativeString<TCharPtr> ns = new("Hello world!");
39+
using NativeStruct<Arg> nstruct = new(new Arg() { x = 7, y = 5 });
40+
41+
using dynamic l = new ConariX(Assets.PrjNetfxRuntime);
42+
43+
try
44+
{
45+
IntPtr ptr = l.callme<IntPtr>(ns, nstruct);
46+
47+
if(ptr != IntPtr.Zero)
48+
{
49+
using NativeArray<int> nr = new(4, ptr);
50+
51+
Assert.Equal(-1, nr[0]);
52+
Assert.Equal(7, nr[1]);
53+
Assert.Equal(1, nr[2]);
54+
Assert.Equal(5, nr[3]);
55+
56+
nstruct.read(out Arg upd);
57+
Assert.Equal(8, upd.x); // due to structure.Access().write<int>(8);
58+
59+
// possible alternatives ~
60+
using NativeStruct<Arg> nstruct2 = new((IntPtr)nstruct);
61+
Assert.Equal(upd.x, nstruct2.Data.x);
62+
Assert.Equal(upd.x, nstruct.Native.f<int>("x")._.x);
63+
64+
using NativeArray<int> nr2 = new(2, nstruct2);
65+
Assert.Equal(upd.x, nr2[0]);
66+
}
67+
68+
TCharPtr r = l.callme<TCharPtr>(ns + " and You 👋", nstruct);
69+
Assert.Equal("Рад знакомству 🤝 どうぞよろしく", r);
70+
}
71+
finally
72+
{
73+
l.free();
74+
}
75+
}
76+
77+
[Fact]
78+
public void CallmeTest2()
79+
{
80+
using dynamic l = new ConariX(Assets.PrjNetfxRuntime);
81+
82+
using NativeString<CharPtr> ns = new("Hello world");
83+
84+
try
85+
{
86+
IntPtr ptr = l.callme<IntPtr>(ns);
87+
Assert.Equal(IntPtr.Zero, ptr);
88+
}
89+
finally
90+
{
91+
l.free();
92+
}
93+
}
94+
95+
[Fact]
96+
public void ThrowExceptionTest1()
97+
{
98+
using ConariL l = new(Assets.PrjNetfxRuntime);
99+
100+
Assert.Equal
101+
(
102+
"こんにちは!",
103+
Assert.Throws<NotImplementedException>(() => { l.bind<Action>("throwException")(); }).Message
104+
);
105+
}
106+
107+
struct Arg { public int x, y; }
108+
}
109+
}

0 commit comments

Comments
 (0)