C
C#2mo ago
ValorZard

How to make bindings for a native library using ClangSharp?

For context, this is the library that I'm trying to make bindings for: https://github.com/paullouisageneau/libjuice/tree/master (and i'd ideally love to add this to nuget as a package or something)
GitHub
GitHub - paullouisageneau/libjuice: JUICE is a UDP Interactive Conn...
JUICE is a UDP Interactive Connectivity Establishment library - paullouisageneau/libjuice
32 Replies
ValorZard
ValorZardOP2mo ago
@あんたのお尻が大きくて私が気絶したいです yeah i thought it was simpel too, but i kept running into this error
PS C:\Github\libjuice> ClangSharpPInvokeGenerator -f .\include\juice\juice.h -n LibJuice -o .
Processing '.\include\juice\juice.h'
Unhandled exception: System.UnauthorizedAccessException: Access to the path 'C:\Github\libjuice' is denied.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.FileStream..ctor(String path, FileMode mode)
at ClangSharp.PInvokeGenerator.<>c.<.ctor>b__44_0(String path) in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 136
at ClangSharp.PInvokeGenerator.Close() in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 240
at ClangSharp.PInvokeGenerator.Dispose(Boolean isDisposing) in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 2322
at ClangSharp.PInvokeGenerator.Dispose() in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 1657
at ClangSharp.Program.Run(InvocationContext context) in /_/sources/ClangSharpPInvokeGenerator/Program.cs:line 826
at System.CommandLine.Handler.<>c__DisplayClass1_0`1.<SetHandler>b__0(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.<>c__DisplayClass2_0.<.ctor>g__Handle|0(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()
PS C:\Github\libjuice> ClangSharpPInvokeGenerator -f .\include\juice\juice.h -n LibJuice -o .
Processing '.\include\juice\juice.h'
Unhandled exception: System.UnauthorizedAccessException: Access to the path 'C:\Github\libjuice' is denied.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.FileStream..ctor(String path, FileMode mode)
at ClangSharp.PInvokeGenerator.<>c.<.ctor>b__44_0(String path) in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 136
at ClangSharp.PInvokeGenerator.Close() in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 240
at ClangSharp.PInvokeGenerator.Dispose(Boolean isDisposing) in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 2322
at ClangSharp.PInvokeGenerator.Dispose() in /_/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs:line 1657
at ClangSharp.Program.Run(InvocationContext context) in /_/sources/ClangSharpPInvokeGenerator/Program.cs:line 826
at System.CommandLine.Handler.<>c__DisplayClass1_0`1.<SetHandler>b__0(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.<>c__DisplayClass2_0.<.ctor>g__Handle|0(InvocationContext context)
at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()
JenyaRostov
JenyaRostov2mo ago
run cmd with admin rights?
Aaron
Aaron2mo ago
this seemed to work fine for me
No description
Aaron
Aaron2mo ago
No description
ValorZard
ValorZardOP2mo ago
huh alright lemme try im on windows if that helps
Aaron
Aaron2mo ago
course you dont need the last line on windows (and that -wcc is kinda incorrect, it just makes the output cleaner)
ValorZard
ValorZardOP2mo ago
No description
ValorZard
ValorZardOP2mo ago
like this?
ValorZard
ValorZardOP2mo ago
No description
Aaron
Aaron2mo ago
needs to be in quotes in powershell
ValorZard
ValorZardOP2mo ago
gotchu
PS C:\Github\libjuice> ClangSharpPInvokeGenerator "@generate.rsp"
Error: Parsing failed for 'include\juice.h' due to 'CXError_Failure'.
Skipping 'include\juice.h' due to one or more errors listed above.
PS C:\Github\libjuice> ClangSharpPInvokeGenerator "@generate.rsp"
Error: Parsing failed for 'include\juice.h' due to 'CXError_Failure'.
Skipping 'include\juice.h' due to one or more errors listed above.
include\juice.h

-c
preview-codegen
multi-file
generate-helper-types

-wcc
*=winapi

-n
Juice

-l
libjuice

-o
Generated
include\juice.h

-c
preview-codegen
multi-file
generate-helper-types

-wcc
*=winapi

-n
Juice

-l
libjuice

-o
Generated
Aaron
Aaron2mo ago
wasnt it include/juice/juice.h
ValorZard
ValorZardOP2mo ago
ah okay cool, now what do i do?
Aaron
Aaron2mo ago
you should just have output you can use in Generated
ValorZard
ValorZardOP2mo ago
hm, how do i use it? do i just drop it into a sln or something?
Aaron
Aaron2mo ago
into whatever project, yah
ValorZard
ValorZardOP2mo ago
huh, i guess i could just link this as a folder
ValorZard
ValorZardOP2mo ago
No description
ValorZard
ValorZardOP2mo ago
uh so how do i actually use this? i can't just do using Juice;
Aaron
Aaron2mo ago
put the Generated folder in the project folder
ValorZard
ValorZardOP2mo ago
huh and then do i just drag the dll in there as well?
Aaron
Aaron2mo ago
uhh there's a bit about packaging native dependencies on msdn https://learn.microsoft.com/en-us/nuget/create-packages/native-files-in-net-packages
Native files in .NET packages
How to pack native libraries in .NET packages
Aaron
Aaron2mo ago
but otherwise you just tell it to copy to your output
ValorZard
ValorZardOP2mo ago
oh man this is really annoying LOL gonna do this later, but trying to convert the tests into c# is really werid haha
ValorZard
ValorZardOP2mo ago
ValorZard
ValorZardOP2mo ago
How would you rewrite this in c#? I was running into really weird pointer conversion stuff and sbyte And it doesn’t feel like I should have to do that
arion
arion2mo ago
They give a good explanation as to why that is over here. https://github.com/dotnet/ClangSharp/issues/428#issuecomment-1454811249 You can create a string with a sbyte* via new string(ptr) This creates an ansi or utf8 string iirc
ValorZard
ValorZardOP2mo ago
Is there a way to do it the other way around?
arion
arion2mo ago
You want a sbyte* from a string?
ValorZard
ValorZardOP2mo ago
Ye
arion
arion2mo ago
I don't entirely know a way that's built in so i wrote 1 myself https://github.com/JustArion/Managed_Corsair-SDK/blob/development/src/CorsairSDK/Device/Internal/UTF8StringHandle.cs While you dont really need to hold on to the lifetime of the string via usings, it it heavily recommended to pass the entire class into your methods instead of just a sbyte* eg.
unsafe void SomeMethodOfMine(sbyte* ptr)
{
// This is bad
// Your code that uses ptr here
}
unsafe void SomeMethodOfMine(sbyte* ptr)
{
// This is bad
// Your code that uses ptr here
}
unsafe void SomeMethodOfMine(UTF8StringHandle handle)
{
// This is good
// Your code that uses ptr here
}
unsafe void SomeMethodOfMine(UTF8StringHandle handle)
{
// This is good
// Your code that uses ptr here
}
You don't want your string to be disposed when its inside the C/C++ code The technical explanation is that the handle won't be GCed if its still in the same stack frame that you're invoking the bindings (Example can be seen here) C# strings are stored behind the scenes as UTF16 so we convert to UTF8
ValorZard
ValorZardOP2mo ago
Huh interesting. Going to come back to this later
Want results from more Discord servers?
Add your server