Skip to content

Commit dc076f2

Browse files
committed
Minor update (a bunch of changes, see description)
* Fix `Lazy=false` (eager module) not working * Fix name collision for overloaded functions * Implement SuppressGCTransition, SymbolPrefix, SymbolSuffix, Inherited * Change Ordinal to int (still a WIP) * Optimize code generation * Add documentation for attributes * Add Example project * Update editorconfig and reformat files
1 parent 0d2cbf7 commit dc076f2

14 files changed

Lines changed: 877 additions & 227 deletions

.editorconfig

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,90 @@
11
# http://EditorConfig.org
2+
3+
# Top-most EditorConfig file
24
root = true
35

4-
[**.cs]
6+
# Default settings for all files
7+
[*]
8+
charset = utf-8
59
end_of_line = crlf
10+
indent_size = 4
11+
indent_style = tab
12+
trim_trailing_whitespace = false
13+
insert_final_newline = false
14+
15+
16+
[**.cs]
17+
indent_size = 2
18+
indent_style = space
19+
trim_trailing_whitespace = true
620
insert_final_newline = true
7-
charset = utf-8
21+
22+
23+
[**.md]
24+
indent_size = 2
25+
indent_style = space
26+
trim_trailing_whitespace = false
27+
insert_final_newline = true
28+
29+
30+
# Solution files
31+
[**.{sln,slnf,slnx}]
32+
indent_size = 4
33+
indent_style = space
34+
trim_trailing_whitespace = true
35+
insert_final_newline = true
36+
37+
38+
# XML project files
39+
[**.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,nativeproj,locproj}]
40+
indent_size = 4
41+
indent_style = space
42+
trim_trailing_whitespace = true
43+
insert_final_newline = true
44+
45+
46+
# XML config files
47+
[**.{xml,imxml,stylecop,props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
48+
indent_size = 4
49+
indent_style = space
50+
trim_trailing_whitespace = true
51+
insert_final_newline = true
52+
53+
54+
# JSON files
55+
[**.json]
56+
indent_size = 2
57+
indent_style = space
58+
insert_final_newline = true
59+
trim_trailing_whitespace = true
60+
61+
62+
# YAML config files
63+
[**.{yml,yaml}]
64+
indent_size = 2
65+
indent_style = space
66+
insert_final_newline = true
67+
trim_trailing_whitespace = true
68+
69+
70+
# Powershell files
71+
[**.ps1]
72+
indent_size = 2
73+
indent_style = space
74+
insert_final_newline = true
75+
trim_trailing_whitespace = true
76+
77+
78+
# Shell script files
79+
[**.sh]
80+
indent_size = 2
881
indent_style = space
82+
insert_final_newline = true
83+
trim_trailing_whitespace = true
84+
85+
86+
[**.{bat,cmd}]
987
indent_size = 2
88+
indent_style = tab
89+
insert_final_newline = true
1090
trim_trailing_whitespace = true

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
run: dotnet restore
5353

5454
- name: Build solution
55-
run: dotnet build -c Release --no-restore
55+
run: dotnet build -c Release --no-restore --no-incremental
5656

5757
- name: Create nupkg
5858
run: dotnet pack -c Release --no-build -o ./nupkg

Example/Example.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
global using NativeInvoke; // to import our attributes in your project
2+
3+
using System.Runtime.CompilerServices;
4+
using System.Runtime.InteropServices;
5+
6+
using BOOL = int; // Win32 BOOL is 4-bytes (0=false, 1=true)
7+
using DWORD = uint; // double-word
8+
9+
namespace Example;
10+
11+
#if NET6_0_OR_GREATER
12+
[System.Runtime.Versioning.SupportedOSPlatform("windows")] // Optional (for clarity)
13+
#endif
14+
public interface IKernel32<TBool, TDWord>
15+
where TBool : unmanaged
16+
where TDWord : unmanaged
17+
{
18+
[NativeImportMethod("Beep")]
19+
TBool Boop(TDWord frequency, TDWord duration); // generic with explicit entry point
20+
21+
[NativeImportMethod(CallingConvention = CallingConvention.StdCall)]
22+
BOOL Boop(int frequency, int duration); // calling convention override
23+
24+
BOOL Beep(TDWord frequency, TDWord duration); // no attribute
25+
26+
[NativeImportMethod(null)]
27+
void IgnoreMe(); // should be skipped
28+
}
29+
30+
internal sealed partial record Win32
31+
{
32+
private const string LibName = "kernel32";
33+
34+
[NativeImport(
35+
LibName, // Specify native library name
36+
Lazy = false, // Whether to use lazy or eager module loading
37+
CallingConvention = CallingConvention.Cdecl, // Define the default calling convention
38+
SymbolPrefix = "begin_", // Define common symbol prefix
39+
SymbolSuffix = "_end", // Define common symbol suffix
40+
Inherited = false // Whether to consider interface inheritance members
41+
)]
42+
//internal static partial IKernel32 Kernel32 { get; }
43+
internal static partial IKernel32<BOOL, DWORD> Kernel32 { get; }
44+
}
45+
46+
internal static partial class Program
47+
{
48+
[LibraryImport("kernel32", EntryPoint = "Beep")]
49+
private static partial BOOL PlayBeep(DWORD f, DWORD d);
50+
51+
private static void Main()
52+
{
53+
Win32.Kernel32.Boop(750, 2000);
54+
PlayBeep(750, 2000);
55+
}
56+
}

Example/Example.csproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
10+
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
11+
<CompilerGeneratedFilesOutputPath>$(IntermediateOutputPath)Generated</CompilerGeneratedFilesOutputPath>
12+
<!--<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)Generated</CompilerGeneratedFilesOutputPath>-->
13+
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\NativeInvoke\NativeInvoke.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true"/>
18+
</ItemGroup>
19+
20+
</Project>

NativeInvoke.slnx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<Solution>
2-
<Project Path="NativeInvoke/NativeInvoke.csproj" />
2+
<Project Path="Example/Example.csproj"/>
3+
<Project Path="NativeInvoke/NativeInvoke.csproj"/>
34
</Solution>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
; Shipped analyzer releases
22
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
33

4+
## 1.0.0
5+
6+
### New Rules
7+
8+
Rule ID | Category | Severity | Notes
9+
--------|----------|----------|-------
10+
NINVK001 | NativeInvoke | Error | Diagnostics
11+
NINVK002 | NativeInvoke | Error | Diagnostics
12+
NINVK003 | NativeInvoke | Error | Diagnostics
13+
NINVK004 | NativeInvoke | Error | Diagnostics
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
; Unshipped analyzer release
22
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
3-

NativeInvoke/Generator/Diagnostics.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,31 @@ internal static partial class Diagnostics
55
public static readonly DiagnosticDescriptor TypeMustBePartial = new(
66
id: "NINVK001",
77
title: "Containing type must be static partial class",
8-
messageFormat: "Type '{0}' must be a partial to use [NativeImport] on a property.",
8+
messageFormat: "Type '{0}' must be a partial to use [NativeImport] on a property",
99
category: "NativeInvoke",
1010
defaultSeverity: DiagnosticSeverity.Error,
1111
isEnabledByDefault: true);
1212

1313
public static readonly DiagnosticDescriptor PropertyMustBeStaticPartial = new(
1414
id: "NINVK002",
1515
title: "Property must be static partial",
16-
messageFormat: "Property '{0}' must be declared as 'static partial' to use [NativeImport].",
16+
messageFormat: "Property '{0}' must be declared as 'static partial' to use [NativeImport]",
1717
category: "NativeInvoke",
1818
defaultSeverity: DiagnosticSeverity.Error,
1919
isEnabledByDefault: true);
2020

2121
public static readonly DiagnosticDescriptor PropertyTypeMustBeInterface = new(
2222
id: "NINVK003",
2323
title: "Property type must be an interface",
24-
messageFormat: "Property '{0}' must have an interface type to use [NativeImport].",
24+
messageFormat: "Property '{0}' must have an interface type to use [NativeImport]",
2525
category: "NativeInvoke",
2626
defaultSeverity: DiagnosticSeverity.Error,
2727
isEnabledByDefault: true);
2828

2929
public static readonly DiagnosticDescriptor NonBlittableSignature = new(
3030
id: "NINVK004",
3131
title: "Non-blittable signature",
32-
messageFormat: "Method '{0}' has a non-blittable signature and cannot be generated.",
32+
messageFormat: "Method '{0}' has a non-blittable signature and cannot be generated",
3333
category: "NativeInvoke",
3434
defaultSeverity: DiagnosticSeverity.Error,
3535
isEnabledByDefault: true);

0 commit comments

Comments
 (0)