Skip to content

Commit 6b0b66e

Browse files
committed
Add smoke test from dotnet#113
1 parent 71f945b commit 6b0b66e

File tree

4 files changed

+228
-0
lines changed

4 files changed

+228
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
project (SharedLibrary)
2+
include_directories(${INC_PLATFORM_DIR})
3+
4+
add_executable (SharedLibrary SharedLibrary.cpp)
5+
6+
if (CLR_CMAKE_TARGET_UNIX)
7+
target_link_libraries (SharedLibrary ${CMAKE_DL_LIBS})
8+
endif()
9+
10+
# add the install targets
11+
install (TARGETS PInvokeNative DESTINATION bin)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#ifdef TARGET_WINDOWS
5+
#include "windows.h"
6+
#else
7+
#include "dlfcn.h"
8+
#endif
9+
#include "stdio.h"
10+
#include "string.h"
11+
12+
#ifndef TARGET_WINDOWS
13+
#define __stdcall
14+
#endif
15+
16+
// typedef for shared lib exported methods
17+
typedef int(__stdcall *f_ReturnsPrimitiveInt)();
18+
typedef bool(__stdcall *f_ReturnsPrimitiveBool)();
19+
typedef char(__stdcall *f_ReturnsPrimitiveChar)();
20+
typedef void(__stdcall *f_EnsureManagedClassLoaders)();
21+
22+
#ifdef TARGET_WINDOWS
23+
int main()
24+
#else
25+
int main(int argc, char* argv[])
26+
#endif
27+
{
28+
#ifdef TARGET_WINDOWS
29+
HINSTANCE handle = LoadLibrary("SharedLibrary.dll");
30+
#elif __APPLE__
31+
void *handle = dlopen(strcat(argv[0], ".dylib"), RTLD_LAZY);
32+
#else
33+
void *handle = dlopen(strcat(argv[0], ".so"), RTLD_LAZY);
34+
#endif
35+
36+
if (!handle)
37+
return 1;
38+
39+
#ifdef TARGET_WINDOWS
40+
f_ReturnsPrimitiveInt returnsPrimitiveInt = (f_ReturnsPrimitiveInt)GetProcAddress(handle, "ReturnsPrimitiveInt");
41+
f_ReturnsPrimitiveBool returnsPrimitiveBool = (f_ReturnsPrimitiveBool)GetProcAddress(handle, "ReturnsPrimitiveBool");
42+
f_ReturnsPrimitiveChar returnsPrimitiveChar = (f_ReturnsPrimitiveChar)GetProcAddress(handle, "ReturnsPrimitiveChar");
43+
f_EnsureManagedClassLoaders ensureManagedClassLoaders = (f_EnsureManagedClassLoaders)GetProcAddress(handle, "EnsureManagedClassLoaders");
44+
f_ReturnsPrimitiveInt checkSimpleGCCollect = (f_ReturnsPrimitiveInt)GetProcAddress(handle, "CheckSimpleGCCollect");
45+
f_ReturnsPrimitiveInt checkSimpleExceptionHandling = (f_ReturnsPrimitiveInt)GetProcAddress(handle, "CheckSimpleExceptionHandling");
46+
#else
47+
f_ReturnsPrimitiveInt returnsPrimitiveInt = (f_ReturnsPrimitiveInt)dlsym(handle, "ReturnsPrimitiveInt");
48+
f_ReturnsPrimitiveBool returnsPrimitiveBool = (f_ReturnsPrimitiveBool)dlsym(handle, "ReturnsPrimitiveBool");
49+
f_ReturnsPrimitiveChar returnsPrimitiveChar = (f_ReturnsPrimitiveChar)dlsym(handle, "ReturnsPrimitiveChar");
50+
f_EnsureManagedClassLoaders ensureManagedClassLoaders = (f_EnsureManagedClassLoaders)dlsym(handle, "EnsureManagedClassLoaders");
51+
f_ReturnsPrimitiveInt checkSimpleGCCollect = (f_ReturnsPrimitiveInt)dlsym(handle, "CheckSimpleGCCollect");
52+
f_ReturnsPrimitiveInt checkSimpleExceptionHandling = (f_ReturnsPrimitiveInt)dlsym(handle, "CheckSimpleExceptionHandling");
53+
#endif
54+
55+
if (returnsPrimitiveInt() != 10)
56+
return 1;
57+
58+
if (!returnsPrimitiveBool())
59+
return 2;
60+
61+
if (returnsPrimitiveChar() != 'a')
62+
return 3;
63+
64+
// As long as no unmanaged exception is thrown
65+
// managed class loaders were initialized successfully
66+
ensureManagedClassLoaders();
67+
68+
if (checkSimpleGCCollect() != 100)
69+
return 4;
70+
71+
if (checkSimpleExceptionHandling() != 100)
72+
return 5;
73+
74+
// CoreRT is not designed to be unloadable, so this won't actually unload the library properly. Verify that attempt
75+
// to unload the library does not to crash at least.
76+
#ifdef TARGET_WINDOWS
77+
FreeLibrary(handle);
78+
#else
79+
// TODO: How to pin the library in memory on Unix?
80+
// dlclose(handle);
81+
#endif
82+
83+
return 100;
84+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
8+
namespace SharedLibrary
9+
{
10+
public class ClassLibrary
11+
{
12+
[UnmanagedCallersOnly(EntryPoint = "ReturnsPrimitiveInt", CallConvs = new Type[] { typeof(CallConvStdcall) })]
13+
public static int ReturnsPrimitiveInt()
14+
{
15+
return 10;
16+
}
17+
18+
[UnmanagedCallersOnly(EntryPoint = "ReturnsPrimitiveBool", CallConvs = new Type[] { typeof(CallConvStdcall) })]
19+
public static bool ReturnsPrimitiveBool()
20+
{
21+
return true;
22+
}
23+
24+
[UnmanagedCallersOnly(EntryPoint = "ReturnsPrimitiveChar", CallConvs = new Type[] { typeof(CallConvStdcall) })]
25+
public static char ReturnsPrimitiveChar()
26+
{
27+
return 'a';
28+
}
29+
30+
[UnmanagedCallersOnly(EntryPoint = "EnsureManagedClassLoaders", CallConvs = new Type[] { typeof(CallConvStdcall) })]
31+
public static void EnsureManagedClassLoaders()
32+
{
33+
Random random = new Random();
34+
random.Next();
35+
}
36+
37+
[UnmanagedCallersOnly(EntryPoint = "CheckSimpleExceptionHandling", CallConvs = new Type[] { typeof(CallConvStdcall) })]
38+
public static int CheckSimpleExceptionHandling()
39+
{
40+
int result = 10;
41+
42+
try
43+
{
44+
Console.WriteLine("Throwing exception");
45+
throw new Exception();
46+
}
47+
catch when (result == 10)
48+
{
49+
result += 20;
50+
}
51+
finally
52+
{
53+
result += 70;
54+
}
55+
56+
return result;
57+
}
58+
59+
private static bool s_collected;
60+
61+
class ClassWithFinalizer
62+
{
63+
~ClassWithFinalizer() { s_collected = true; }
64+
}
65+
66+
[MethodImpl(MethodImplOptions.NoInlining)]
67+
private static void MakeGarbage()
68+
{
69+
GC.Collect();
70+
GC.WaitForPendingFinalizers();
71+
GC.Collect();
72+
73+
object[] arr = new object[1024 * 1024];
74+
for (int i = 0; i < arr.Length; i++)
75+
arr[i] = new object();
76+
77+
new ClassWithFinalizer();
78+
}
79+
80+
[UnmanagedCallersOnly(EntryPoint = "CheckSimpleGCCollect", CallConvs = new Type[] { typeof(CallConvStdcall) })]
81+
public static int CheckSimpleGCCollect()
82+
{
83+
string myString = string.Format("Hello {0}", "world");
84+
85+
MakeGarbage();
86+
87+
Console.WriteLine("Triggering GC");
88+
GC.Collect();
89+
GC.WaitForPendingFinalizers();
90+
GC.Collect();
91+
92+
return s_collected ? (myString == "Hello world" ? 100 : 1) : 2;
93+
}
94+
}
95+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Library</OutputType>
4+
<CLRTestKind>BuildAndRun</CLRTestKind>
5+
<CLRTestPriority>0</CLRTestPriority>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
9+
<PropertyGroup>
10+
<NativeAotProjectLines>
11+
<![CDATA[
12+
<PropertyGroup>
13+
<OutputType>Library</OutputType>
14+
<NativeLib>Shared</NativeLib>
15+
</PropertyGroup>
16+
]]>
17+
</NativeAotProjectLines>
18+
19+
<CLRTestBatchPreCommands><![CDATA[
20+
$(CLRTestBatchPreCommands)
21+
mkdir native 2>nul
22+
copy /y SharedLibrary.exe native\SharedLibrary.exe
23+
]]></CLRTestBatchPreCommands>
24+
25+
<BashCLRTestPreCommands><![CDATA[
26+
$(BashCLRTestPreCommands)
27+
mkdir -p native
28+
cp SharedLibrary native/SharedLibrary
29+
]]></BashCLRTestPreCommands>
30+
</PropertyGroup>
31+
32+
<ItemGroup>
33+
<Compile Include="SharedLibrary.cs" />
34+
</ItemGroup>
35+
<ItemGroup>
36+
<ProjectReference Include="CMakeLists.txt" />
37+
</ItemGroup>
38+
</Project>

0 commit comments

Comments
 (0)