Skip to content

Commit fb2e55c

Browse files
authored
Merge pull request #751 from dotnet/master
Update live with current master
2 parents 1070aaa + a0f5fb2 commit fb2e55c

File tree

14 files changed

+146
-177
lines changed

14 files changed

+146
-177
lines changed

core/extensions/DllMapDemo/Demo.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.IO;
3+
using System.Reflection;
4+
using System.Runtime.InteropServices;
5+
6+
public class DllMapDemo
7+
{
8+
public static void Main()
9+
{
10+
try
11+
{
12+
DllMap.Register(Assembly.GetExecutingAssembly());
13+
int thirty = NativeSum(10, 20);
14+
Console.WriteLine($"OldLib.NativeSum(10,20) = {thirty}");
15+
}
16+
catch (Exception e)
17+
{
18+
Console.WriteLine($"Error: {e.Message} Line: {e.Source}");
19+
}
20+
}
21+
22+
[DllImport("OldLib")]
23+
static extern int NativeSum(int arg1, int arg2);
24+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>netcoreapp3.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<None Include="Demo.xml">
8+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
9+
</None>
10+
</ItemGroup>
11+
</Project>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<configuration>
2+
<dllmap dll="OldLib" target="NewLib"/>
3+
</configuration>

core/extensions/DllMapDemo/Map.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Runtime.InteropServices;
7+
using System.Xml.Linq;
8+
9+
public static class DllMap
10+
{
11+
// Register a call-back for native library resolution.
12+
public static void Register(Assembly assembly)
13+
{
14+
NativeLibrary.SetDllImportResolver(assembly, MapAndLoad);
15+
}
16+
17+
// The callback: which loads the mapped libray in place of the original
18+
private static IntPtr MapAndLoad(string libraryName, Assembly assembly, DllImportSearchPath? dllImportSearchPath)
19+
{
20+
string mappedName = null;
21+
mappedName = MapLibraryName(assembly.Location, libraryName, out mappedName) ? mappedName : libraryName;
22+
return NativeLibrary.Load(mappedName, assembly, dllImportSearchPath);
23+
}
24+
25+
// Parse the assembly.xml file, and map the old name to the new name of a library.
26+
private static bool MapLibraryName(string assemblyLocation, string originalLibName, out string mappedLibName)
27+
{
28+
string xmlPath = Path.Combine(Path.GetDirectoryName(assemblyLocation),
29+
Path.GetFileNameWithoutExtension(assemblyLocation) + ".xml");
30+
mappedLibName = null;
31+
32+
if (!File.Exists(xmlPath))
33+
return false;
34+
35+
XElement root = XElement.Load(xmlPath);
36+
var map =
37+
(from el in root.Elements("dllmap")
38+
where (string)el.Attribute("dll") == originalLibName
39+
select el).SingleOrDefault();
40+
41+
if (map != null)
42+
mappedLibName = map.Attribute("target").Value;
43+
44+
return (mappedLibName != null);
45+
}
46+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdio.h>
2+
3+
#if defined(__GNUC__)
4+
#define EXPORT extern "C" __attribute__((visibility("default")))
5+
#elif defined(_MSC_VER)
6+
#define EXPORT extern "C" __declspec(dllexport)
7+
#endif
8+
9+
extern "C" EXPORT int NativeSum(int a, int b)
10+
{
11+
return a + b;
12+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# DllMap Demo
2+
3+
This sample illustrates the use of NativeLibrary APIs to implement library name mappings similar to the [Mono](https://www.mono-project.com/) [Dllmap](http://www.mono-project.com/docs/advanced/pinvoke/dllmap/) feature.
4+
5+
## NativeLibrary APIs
6+
7+
.Net Core 3.0 provides a rich set of APIs to manage native libraries:
8+
9+
- [NativeLibrary APIs](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary?view=netcore-3.0): Perform operations on native libraries (such as `Load()`, `Free()`, get the address of an exported symbol, etc.) in a platform-independent way from managed code.
10+
- [DllImport Resolver callback](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary.setdllimportresolver?view=netcore-3.0): Gets a callback for first-chance native library resolution using custom logic.
11+
- [Native Library Resolve event](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.resolvingunmanageddll?view=netcore-3.0): Get an event for last-chance native library resolution using custom logic.
12+
13+
## Library Mapping
14+
15+
These APIs can be used to implement custom native library resolution logic, including DllMap, as illustrated in this example. The sample demonstrates:
16+
17+
- An [app](Demo.cs) that pInvokes a method in `OldLib`, but runs in an environment where only [`NewLib`](NewLib.cpp) is available.
18+
- The [XML file](Demo.xml) that maps the library name from `OldLib` to `NewLib`.
19+
- The [Map](Map.cs) implementation, which parses the above mapping and uses `NativeLibrary` APIs to load the correct library.
20+
21+
## Build and Run
22+
23+
1. Install .NET Core 3.0 Preview 3 or newer.
24+
25+
2. Use the .NET Core SDK to build the project via `dotnet build`.
26+
27+
3. Build the native component `NewLib.cpp` as a dynamic library, using the platform's native toolset.
28+
29+
Place the generated native library (`NewLib.dll` / `libNewLib.so` / `libNewLib.dylib`) in the `dotnet build` output directory.
30+
31+
4. Run the app with `dotnet run`

snippets/csharp/VS_Snippets_CLR/environment.IsServerGC/CS/isg.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
using System;
33
using System.Runtime;
44

5-
class Sample
5+
class Sample
66
{
7-
public static void Main()
7+
public static void Main()
88
{
9-
string result;
9+
string result;
1010

11-
if (GCSettings.IsServerGC == true)
12-
result = "server";
13-
else
14-
result = "workstation";
15-
Console.WriteLine("The {0} garbage collector is running.", result);
11+
if (GCSettings.IsServerGC == true)
12+
result = "server";
13+
else
14+
result = "workstation";
15+
Console.WriteLine("The {0} garbage collector is running.", result);
1616
}
1717
}
1818
// The example displays output like the following:
1919
// The workstation garbage collector is running.
20-
//</snippet1>
20+
//</snippet1>

snippets/csharp/VS_Snippets_WebNet/System.Configuration.ConfigurationManager/CS/configurationmanager.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public static class UsingConfigurationManager
119119
// ConfigurationUserLevel userLevel) method to
120120
// get the configuration file.
121121
// It also creates a custom ConsoleSection and
122-
// sets its ConsoleEment BackgroundColor and
122+
// sets its ConsoleElement BackgroundColor and
123123
// ForegroundColor properties to blue and yellow
124124
// respectively. Then it uses these properties to
125125
// set the console colors.
@@ -239,7 +239,7 @@ public static void GetRoamingConfiguration()
239239
// OpenExeConfiguration(string)method
240240
// to get the application configuration file.
241241
// It also creates a custom ConsoleSection and
242-
// sets its ConsoleEment BackgroundColor and
242+
// sets its ConsoleElement BackgroundColor and
243243
// ForegroundColor properties to black and white
244244
// respectively. Then it uses these properties to
245245
// set the console colors.
@@ -496,7 +496,7 @@ public static void MapMachineConfiguration()
496496
// This function uses the OpenMappedExeConfiguration
497497
// method to access a new configuration file.
498498
// It also gets the custom ConsoleSection and
499-
// sets its ConsoleEment BackgroundColor and
499+
// sets its ConsoleElement BackgroundColor and
500500
// ForegroundColor properties to green and red
501501
// respectively. Then it uses these properties to
502502
// set the console colors.
@@ -707,4 +707,4 @@ static void Main(string[] args)
707707
}
708708
#endregion
709709

710-
// </Snippet1>
710+
// </Snippet1>

snippets/csharp/language-reference/keywords/switch/type-pattern.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private static void ShowCollectionInformation(object coll)
3434
break;
3535
case IEnumerable ie:
3636
string result = "";
37-
foreach (var item in ie)
37+
foreach (var e in ie)
3838
result += "${e} ";
3939
Console.WriteLine(result);
4040
break;

snippets/csharp/language-reference/keywords/switch/type-pattern2.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private static void ShowCollectionInformation(object coll)
3636
else if (coll is IEnumerable) {
3737
IEnumerable ie = (IEnumerable) coll;
3838
string result = "";
39-
foreach (var item in ie)
39+
foreach (var e in ie)
4040
result += "${e} ";
4141
Console.WriteLine(result);
4242
}

0 commit comments

Comments
 (0)