Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] Support std::shared_ptr (and complete Github Actions workflow example file with generating bindings of popular libraries) #1860

Open
vadimkantorov opened this issue Aug 19, 2024 · 27 comments

Comments

@vadimkantorov
Copy link

vadimkantorov commented Aug 19, 2024

UPD: the missing std::shared_ptr<T> support context is in the message #1860 (comment). Currently this support seems missing, and shared_ptr/unique_ptr are quite common types in modern C++ APIs to be processed

JavaCpp seems to support binding std::shared_ptr<T>: bytedeco/javacpp#623

Below is a very long thread where we ended up rolling a fully complete GitHub Actions Workflow file.


GitHub Actions allow for a reproducible environment, so pulling in-tree a collection of GitHub Actions workflow files for popular libraries from https://github.com/mono/CppSharp?tab=readme-ov-file#users (like ffmpeg or dearimgui) could be a great start for new users showcasing the install procedures.

And sometimes it would be possible to just copy the filly self-contained workflow-file and modify it to create a command for binding-generation for a new library. Then users could send PRs with such workflows/scripts, and they could be tested easily (and especially - tested against new versions of the libraries). Currently https://github.com/mono/CppSharp/tree/main/tests doesn't have many real-world library examples.

I found https://github.com/mono/CppSharp/blob/main/.github/workflows/main.yml. Could it be considered a base for such a workflow file producing a fully functioning llvm+CppSharp install?

@vadimkantorov vadimkantorov changed the title Complete Github Actions with examples of generating bindings for popular libraries (such as ffmpeg or compression libraries) [feature request] Complete Github Actions workflow example file with generating bindings of popular libraries (such as ffmpeg or compression libraries) Aug 19, 2024
@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

I wrote down a primer of a minimalistic workflow file I meant above, looking to generate C API bindings to https://github.com/triton-inference-server/core/blob/main/include/triton/core/tritonserver.h

Does CppSharp absolutely need to have access to CppSharp compiled libtritonserver.so? (module.LibraryDirs / module.Libraries)

How could

name: tritonservercppsharp

on: workflow_dispatch

env:
  PLATFORM: x64

jobs:
  tritonservercppsharp:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v2

      - name: Write down the bindings code
        run: |
          tee tritonservercppsharp.cs <<EOF
            namespace CppSharpTransformer { class DllDemoGenerator : CppSharp.ILibrary {
                public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
                public void SetupPasses(CppSharp.Driver driver) { }
                public void Preprocess(CppSharp.Driver driver, ASTContext ctx) { }
                public void Postprocess(CppSharp.Driver driver, ASTContext ctx) { }
                void ILibrary.Setup(CppSharp.Driver driver) { }
                void Setup(CppSharp.Driver driver) {
                    var options = driver.Options;
                    options.GeneratorKind = GeneratorKind.CSharp;
                    var module = options.AddModule("TritonServerCppSharp");
                    module.IncludeDirs.Add("core/include");
                    module.Headers.Add("triton/core/tritonserver.h");
                    //module.LibraryDirs.Add("/path/to/triton/which/containslibtritonserver.so/");
                    //module.Libraries.Add("libtritonserver.so");
                }
            } }
          EOF

      - name: Clone and build CppSharp
        run: |
          #wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0
          git clone --single-branch --depth 1 --branch v1.1 https://github.com/mono/CppSharp
          cd CppSharp
          bash build/build.sh generate -configuration Release -platform $PLATFORM
          bash build/build.sh download_llvm -platform $PLATFORM
          bash build/build.sh restore -platform $PLATFORM
          bash build/build.sh -platform $PLATFORM -build_only
          find bin
          dotnet --version

      - name: Generating bindings
        run: |
          git clone --single-branch --depth 1 --branch r23.03 https://github.com/triton-inference-server/core
          #"$HOME/.dotnet"
          DOTNET_ROOT=/usr/share/dotnet
          DOTNETSDKVER=$(dotnet --version)
          DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
          DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
          LD_LIBRARY_PATH=CppSharp/bin/Release_x64/ dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ')  -target:library -out:tritonservercppsharp.exe tritonservercppsharp.cs
          dotnet tritonservercppsharp.exe


#      - uses: actions/upload-artifact@v4
#        with:
#          path: CppSharp/bin/Release_x64/

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Could it be considered a base for such a workflow file producing a fully functioning llvm+CppSharp install?

Sure, though this way will compile CppSharp from source (which I personally like, though takes a bit more time).
Another valid approach would be to re-use the Nuget packages published by CppSharp's own CI step.

Does CppSharp absolutely need to have access to CppSharp compiled libtritonserver.so? (module.LibraryDirs / module.Libraries)

IIRC it does not need it, it's only used to find which symbols are provided by the compiled libraries. Especially for C libraries this is not a concern, because header-only inline symbols are usually not present. For C++, it might be a concern depending on the library.

Also to note, for some applications, the CppSharp CLI might be useful since it does not need a custom C# code setup: https://github.com/mono/CppSharp/blob/main/src/CLI/CLI.cs

Customization is harder in that case, but does not have to be the case. I would be very helpful to provide a declarative customization model for simple cases (YAML or even C# script based).

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

Also to note, for some applications, the CppSharp CLI might be useful since it does not need a custom C# code setup

Is there an example of using this tool anywhere? For simple things (and as a baseline), it should indeed be sufficient! I think it's worth advertising a complete example of using this option in the CppSharp's README directly (to have a complete example with dotnet add package and dotnet tool ... or similar) :)

Another valid approach would be to re-use the Nuget packages published by CppSharp's own CI step.

For this case, do I need to do dotnet add package CppSharp? And in both cases, which assemblies do I need to reference for csc.dll to get the basic CppSharp.ILibrary and CppSharp.Driver?

Thanks!

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Is there an example of using this tool anywhere? For simple things (and as a baseline), it should indeed be sufficient!

The test suite is using it, but I would check out the CLI tool directly, as it provides help and description for the parameters:
https://github.com/mono/CppSharp/blob/main/tests/napi/test.sh#L13

For this case, do I need to do dotnet add package CppSharp? And in both cases, which assemblies do I need to reference for csc.dll to get the basic CppSharp.ILibrary and CppSharp.Driver?

I think these are the main ones:

  • CppSharp
  • CppSharp.AST
  • CppSharp.Generator
  • CppSharp.Parser
  • CppSharp.Parser.CppSharp

I am not the best person to ask about Nuget as I rarely use it in my workflows.

But development versions are pushed to GitHub packages:

          dotnet nuget push "*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/mono/index.json" --skip-duplicate

https://github.com/mono/CppSharp/pkgs/nuget/CppSharp

The last version says it was published 4 months ago, so maybe publishing for ongoing development commits is not working correctly after all.

@vadimkantorov
Copy link
Author

For some reason I'm getting problems loading the generated exe (depsite that I copy all the .dlls and .sos in the current dir:

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'CppSharp.Generator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

File name: 'CppSharp.Generator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
/home/runner/work/_temp/388ed1a4-2143-4a23-bfad-d50c5b136892.sh: line 25:  2764 Aborted                 (core dumped) dotnet 
name: tritonservercppsharp

on: workflow_dispatch

env:
  PLATFORM: x64

jobs:
  tritonservercppsharp:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v2

      - name: Write down the bindings code
        run: |
          tee tritonservercppsharp.cs <<EOF
              namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
              public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
              public void SetupPasses(CppSharp.Driver driver) { }
              public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Setup(CppSharp.Driver driver) {
              var options = driver.Options;
              options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
              var module = options.AddModule("TritonServerCppSharp");
              module.IncludeDirs.Add("core/include");
              module.Headers.Add("triton/core/tritonserver.h");
              module.Headers.Add("triton/core/tritonbackend.h");
              module.Headers.Add("triton/core/tritoncache.h");
              module.Headers.Add("triton/core/tritonrepoagent.h");
              //module.LibraryDirs.Add("/path/to/triton/server.so");
              //module.Libraries.Add("tritonserver.so");
              } } }
          EOF

      - name: Clone and build CppSharp
        run: |
          #wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0
          git clone --single-branch --depth 1 https://github.com/mono/CppSharp
          cd CppSharp
          bash build/build.sh generate -configuration Release -platform $PLATFORM
          bash build/build.sh download_llvm -platform $PLATFORM
          bash build/build.sh restore -platform $PLATFORM
          bash build/build.sh -platform $PLATFORM -build_only
          find bin

      - name: Generating bindings
        run: |
          git clone --single-branch --depth 1 https://github.com/triton-inference-server/core
          #"$HOME/.dotnet"
          DOTNET_ROOT=/usr/share/dotnet
          DOTNETSDKVER=$(dotnet --version)
          DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
          DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
          dotnet --version
          dotnet --list-runtimes
          echo $DOTNETSDKVER $DOTNETFWKVER
          # -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll

          #echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
          #dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
          #echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
          #dotnet footest.exe

          find CppSharp/bin/Release_x64 -name 'CppSharp*.dll'
          # -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Runtime.dll -r:CppSharp/bin/Release_x64/CppSharp.CLI.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll

          dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') $(find CppSharp/bin -name "*.dll" -printf '-r:"%p" ') -target:exe -out:tritonservercppsharp.exe tritonservercppsharp.cs
          echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > tritonservercppsharp.runtimeconfig.json
          echo BEFORE
          find CppSharp/bin -name "*.dll" -o -name "*.so" -exec cp {} . ';'
          dotnet tritonservercppsharp.exe

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Have you tried this locally or are you running only on CI?

@vadimkantorov
Copy link
Author

Only on CI. It appears that dotnet does not like the libSystem.Native.so which is found successfully on system path and so it proceeds checking the local directory, it cannot find it and then aborts (after loading 10 various unicode libraries to maybe localize the error message :) ):

2024-08-19T17:11:59.5137891Z [pid  2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5140546Z [pid  2844] openat(AT_FDCWD, "/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.7/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = 15
2024-08-19T17:11:59.5142439Z [pid  2844] read(15, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
2024-08-19T17:11:59.5144051Z [pid  2844] newfstatat(15, "", {st_mode=S_IFREG|0777, st_size=90488, ...}, AT_EMPTY_PATH) = 0
2024-08-19T17:11:59.5145178Z [pid  2844] close(15)                   = 0
2024-08-19T17:11:59.5146687Z [pid  2844] access("", F_OK)            = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5148223Z [pid  2844] access("opt/corebreadcrumbs", F_OK) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5149673Z [pid  2844] readlink("/home", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5151334Z [pid  2844] readlink("/home/runner", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5152984Z [pid  2844] readlink("/home/runner/work", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5154785Z [pid  2844] readlink("/home/runner/work/tritonservercppsharp", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5157228Z [pid  2844] readlink("/home/runner/work/tritonservercppsharp/tritonservercppsharp", 0x7fff9273a7e0, 1023) = -1 EINVAL (Invalid argument)
2024-08-19T17:11:59.5159757Z [pid  2844] stat("/home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.exe", {st_mode=S_IFREG|0644, st_size=4608, ...}) = 0
2024-08-19T17:11:59.5162486Z [pid  2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.exe", O_RDONLY) = 15
2024-08-19T17:11:59.5179454Z [pid  2844] openat(AT_FDCWD, "/proc/self/status", O_RDONLY) = 19
2024-08-19T17:11:59.5180713Z [pid  2844] read(19, "Name:\tdotnet\nUmask:\t0022\nState:\t"..., 2047) = 1442
2024-08-19T17:11:59.5181800Z [pid  2844] close(19)                   = 0
2024-08-19T17:11:59.5240540Z Unhandled exception. [pid  2844] openat(AT_FDCWD, "/home/runner/work/tritonservercppsharp/tritonservercppsharp/libSystem.Native.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
2024-08-19T17:11:59.5242833Z [pid  2844] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 19

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

With the similar command:

 echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
 dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
 echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
dotnet footest.exe

this runs with success

but maybe the problem is that the build command uses a different dotnet / runtime and hence incompat with the runtime I use for running the compiled app?

DOTNET_ROOT=/usr/share/dotnet
          DOTNETSDKVER=$(dotnet --version)
          DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)
          DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
          dotnet --version
          dotnet --list-runtimes
          echo $DOTNETSDKVER $DOTNETFWKVER

2024-08-19T17:11:57.7465811Z 8.0.303
2024-08-19T17:11:57.7524923Z Microsoft.AspNetCore.App 6.0.32 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7526906Z Microsoft.AspNetCore.App 7.0.20 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7528649Z Microsoft.AspNetCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
2024-08-19T17:11:57.7531310Z Microsoft.NETCore.App 6.0.32 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7532927Z Microsoft.NETCore.App 7.0.20 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7534428Z Microsoft.NETCore.App 8.0.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
2024-08-19T17:11:57.7535843Z 8.0.303 8.0.7

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Seems likely, any reason you are installing a separate .NET version instead of using the system one?

@vadimkantorov
Copy link
Author

any reason you are installing a separate .NET version instead of using the system one?

I am not installing any separate .NET. This line is commented out #wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 9.0. I was not sure if Ubuntu comes with the system one or not

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Ok, have you tried without this tritonservercppsharp.runtimeconfig.json? Why are you generating it?

@vadimkantorov
Copy link
Author

It appears in CppSharp.Generator.dll the following. So it seems that build script use the 6.0 version of .NET despite that default (and latest) version is 8.0 (as reported by dotnet --version).

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v6.0",
    "signature": ""
  },

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

Why are you generating it?

Because otherwise dotnet command cannot run the executables built directly with csc :(

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

Ok, must be a new .NET feature, previously I don't remember that being necessary.

8cf6e3f

Maybe this can help, you can pass -target-framework to the build script.

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

I've tried that. This indeed makes "runtimeTarget": {"name": ".NETCoreApp,Version=v8.0", "signature": ""}, into the deps.json, but still same error at the end :(

name: tritonservercppsharp

on: workflow_dispatch

env:
  PLATFORM: x64
  FRAMEWORK: net80
  DOTNET_ROOT: /usr/share/dotnet
  DOTNETSDKVER: 8.0.303
  DOTNETFWKVER: 8.0.7

jobs:
  tritonservercppsharp:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v2

      - name: Write down the bindings code
        run: |
          tee tritonservercppsharp.cs <<EOF
              namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
              public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
              public void SetupPasses(CppSharp.Driver driver) { }
              public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Setup(CppSharp.Driver driver) {
              var options = driver.Options;
              options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
              var module = options.AddModule("TritonServerCppSharp");
              module.IncludeDirs.Add("core/include");
              module.Headers.Add("triton/core/tritonserver.h");
              module.Headers.Add("triton/core/tritonbackend.h");
              module.Headers.Add("triton/core/tritoncache.h");
              module.Headers.Add("triton/core/tritonrepoagent.h");
              //module.LibraryDirs.Add("/path/to/triton/server.so");
              //module.Libraries.Add("tritonserver.so");
              } } }
          EOF

      - name: Clone and build CppSharp
        run: |
          git clone --single-branch --depth 1 https://github.com/mono/CppSharp
          cd CppSharp
          bash build/build.sh generate -configuration Release -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh download_llvm -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh restore -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh -platform $PLATFORM -build_only -target-framework $FRAMEWORK
          find bin

      - name: Generating bindings
        run: |
          git clone --single-branch --depth 1 https://github.com/triton-inference-server/core
          dotnet --version
          dotnet --list-runtimes
          DOTNETLIBDIR="$DOTNET_ROOT/shared/Microsoft.NETCore.App/$DOTNETFWKVER"
          #DOTNETSDKVER=$(dotnet --version)
          #DOTNETFWKVER=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | tail -n 1 | cut -d " " -f2)

          echo 'namespace ProgramNamespace { public static class Program { public static void Main(string[] args) { System.Console.WriteLine("Hello world!"); } } }' > footest.cs
          dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') -target:exe -out:footest.exe footest.cs
          echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > footest.runtimeconfig.json
          dotnet footest.exe

          # -r:CppSharp/bin/Release_x64/CppSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.AST.dll -r:CppSharp/bin/Release_x64/CppSharp.Runtime.dll -r:CppSharp/bin/Release_x64/CppSharp.CLI.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll -r:CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll
          dotnet "$DOTNET_ROOT/sdk/$DOTNETSDKVER/Roslyn/bincore/csc.dll" $(find "$DOTNETLIBDIR" -name "*.dll" -printf '-r:"%p" ') $(find CppSharp/bin -name "*.dll" -printf '-r:"%p" ') -target:exe -out:tritonservercppsharp.exe tritonservercppsharp.cs
          echo '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":"'$DOTNETFWKVER'"}}}' > tritonservercppsharp.runtimeconfig.json
          find CppSharp/bin -name "*.dll" -o -name "*.so" -exec cp {} . ';'
          dotnet tritonservercppsharp.exe || true


      - uses: actions/upload-artifact@v4
        with:
          path: |
            CppSharp/bin/
            tritonservercppsharp.cs
            tritonservercppsharp.runtimeconfig.json
            tritonservercppsharp.exe

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

Ha-ha, it seems that running a csc-compiled file referencing assemblies obtained from dotnet build is somehow incompatible. I guess I need somehow a csproj/sln files examples (that are known to work) referencing the compiled cppsharp assemblies... Very unfortunate that .NET makes it super-hard to just run a C# file without all the ceremonies of csharpproj and runtimeconfig...

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

I've tried also using CSharp.Gen:

cp ./CppSharp/bin/Release_x64/libCppSharp.CppParser.so ./CppSharp/bin/Release_x64/libStd-symbols.so .
mkdir output && ./CppSharp/bin/Release_x64/CSharp.Gen -I core/include/triton/core -o ./output/

More errors:

Generating bindings for CSharp (CSharp)
    Unable to translate macro 'MY_MACRO_TEST2_0' to en enum value: Variable [_invalid] unknown in expression : [0_invalid]
    Linking library libStd-symbols.so...
    Linking success.
    Linking library libCSharp-symbols.so...
    Linking success.
    Symbol not found: _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev
    Symbol not found: _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev
    Symbol not found: HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg
    Symbol not found: ProtectedConstructorDestructor_ProtectedConstructorDestructor

But I couldn't figure out where the symbols _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev, _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev, HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg, ProtectedConstructorDestructor_ProtectedConstructorDestructor are supposed to be coming from? from some CLR shared lib?

So somehow these are some test functions from CppSharp itself:

class SpecializationOfClassWithNonTypeTemplateArgument : public ClassWithNonTypeTemplateArgument<0>

why is it searching for these symbols? Is it trying to run some tests?

@vadimkantorov
Copy link
Author

And the Driver path gives this error. How do I make this Clang resource file findable?

Unhandled exception. System.Exception: Clang resource folder 'lib/clang/18/include' was not found.
   at CppSharp.Parser.ParserOptions.SetupIncludes(TargetPlatform targetPlatform) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Parser/ParserOptions.cs:line 405
   at CppSharp.Parser.ParserOptions.Setup(TargetPlatform targetPlatform) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Parser/ParserOptions.cs:line 293
   at CppSharp.Driver.Setup() in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Generator/Driver.cs:line [57](https://github.com/vadimkantorov/tritonservercppsharp/actions/runs/10461058179/job/28968586864#step:5:58)
   at CppSharp.ConsoleDriver.Run(ILibrary library) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/CppSharp/src/Generator/Driver.cs:line 399
   at CppSharpTransformer.DllDemoGenerator.Main(String[] args) in /home/runner/work/tritonservercppsharp/tritonservercppsharp/tritonservercppsharp.cs:line 2

@tritao
Copy link
Collaborator

tritao commented Aug 19, 2024

I've tried also using CSharp.Gen:

cp ./CppSharp/bin/Release_x64/libCppSharp.CppParser.so ./CppSharp/bin/Release_x64/libStd-symbols.so .
mkdir output && ./CppSharp/bin/Release_x64/CSharp.Gen -I core/include/triton/core -o ./output/

More errors:

Generating bindings for CSharp (CSharp)
    Unable to translate macro 'MY_MACRO_TEST2_0' to en enum value: Variable [_invalid] unknown in expression : [0_invalid]
    Linking library libStd-symbols.so...
    Linking success.
    Linking library libCSharp-symbols.so...
    Linking success.
    Symbol not found: _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev
    Symbol not found: _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev
    Symbol not found: HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg
    Symbol not found: ProtectedConstructorDestructor_ProtectedConstructorDestructor

But I couldn't figure out where the symbols _ZNSpecializationOfClassWithNonTypeTemplateArgumentD2Ev, _ZN48SpecializationOfClassWithNonTypeTemplateArgumentC2Ev, HasPureVirtualWithDefaultArg_HasPureVirtualWithDefaultArg, ProtectedConstructorDestructor_ProtectedConstructorDestructor are supposed to be coming from? from some CLR shared lib?

So somehow these are some test functions from CppSharp itself:

class SpecializationOfClassWithNonTypeTemplateArgument : public ClassWithNonTypeTemplateArgument<0>

why is it searching for these symbols? Is it trying to run some tests?

I think CSharp.Gen is just an artifact built for generating the tests bindings.

And the Driver path gives this error. How do I make this Clang resource file findable?

Sure, there should be a lib/clang folder which should be copied into your bin folder.

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 19, 2024

Okay, I managed to build two variants. Some notes:

  • native library preloads, otherwise it cannot find them despite they are located next to the referenced assemblies, maybe could be fixed by modifying LD_LIBRARY_PATH, but I thought LD_PRELOAD is a bit more explicit here
  • copying the clang headers into the future "bin/Release/x64" dir. the problem is that these headers are searched next to the produced assembly, but with dotnet run, this is a temp directory and certainly not the current directory
  • nasty csproj (disabling implicitly added source files and resetting the working dir). would be welcoming any advice on simplifying it. really wish this was not needed, but csc.dll variant is not easy - maybe it's possible to run it without the dotnet ....exe, but otherwise I could not make it work correctly with CppSharp built using dotnet command

I guess I'll try now to bind the C++ headers at https://github.com/triton-inference-server/developer_tools/tree/main/server/include/triton/developer_tools

My overall impression: complete, fully self-contained examples are desperately needed (and especially of the ./CppSharp/bin/Release_x64/CppSharp.CLI command usage), especially for someone un-versed in msbuild/dotnet command over-complicated madness.

name: tritonservercppsharp

on: workflow_dispatch

env:
  PLATFORM: x64
  FRAMEWORK: net80
  FRAMEWORKDOT: net8.0

jobs:
  tritonservercppsharp:
    runs-on: ubuntu-22.04
    steps:
      - name: Clone tritonserver
        run: |
          git clone --single-branch --depth 1 --branch r24.08 https://github.com/triton-inference-server/core
          git clone --single-branch --depth 1 --branch r24.08 https://github.com/triton-inference-server/developer_tools

      - name: Clone and build CppSharp
        run: |
          git clone --single-branch --depth 1 https://github.com/mono/CppSharp
          cd CppSharp
          bash build/build.sh generate -configuration Release -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh download_llvm -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh restore -platform $PLATFORM -target-framework $FRAMEWORK
          bash build/build.sh -platform $PLATFORM -build_only -target-framework $FRAMEWORK

      - name: Variant 1
        run: ./CppSharp/bin/Release_x64/CppSharp.CLI -m tritonserver -g csharp -p linux -a x64 -o ./variant1/ -I=core/include core/include/triton/core/tritonserver.h core/include/triton/core/tritonbackend.h core/include/triton/core/tritoncache.h core/include/triton/core/tritonrepoagent.h

      - name: Variant 2
        run: |
          echo '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory><OutputType>Exe</OutputType><TargetFramework>net8.0</TargetFramework><EnableDefaultItems>false</EnableDefaultItems></PropertyGroup><ItemGroup><Compile Remove="**/*.cs"/><Compile Include="tritonservercppsharp.cs"/><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Runtime.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.AST.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Generator.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.CLI.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.CSharp.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.Bootstrap.dll</HintPath></Reference><Reference Include="MyAssembly"><HintPath>./CppSharp/bin/Release_x64/CppSharp.Parser.Gen.dll</HintPath></Reference></ItemGroup></Project>' > tritonservercppsharp.csproj
          tee tritonservercppsharp.cs <<EOF
              namespace CppSharpTransformer { public class DllDemoGenerator : CppSharp.ILibrary {
              public static void Main(string[] args) { CppSharp.ConsoleDriver.Run(new DllDemoGenerator()); }
              public void SetupPasses(CppSharp.Driver driver) { }
              public void Preprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Postprocess(CppSharp.Driver driver, CppSharp.AST.ASTContext ctx) { }
              public void Setup(CppSharp.Driver driver) {
              var options = driver.Options;
              options.GeneratorKind = CppSharp.Generators.GeneratorKind.CSharp;
              var module = options.AddModule("tritonserver");
              options.OutputDir = "variant2";
              module.IncludeDirs.Add(".");
              module.IncludeDirs.Add("core/include");
              module.Headers.Add("core/include/triton/core/tritonserver.h");
              module.Headers.Add("core/include/triton/core/tritonbackend.h");
              module.Headers.Add("core/include/triton/core/tritoncache.h");
              module.Headers.Add("core/include/triton/core/tritonrepoagent.h");
              //module.LibraryDirs.Add("/path/to/triton/server.so");
              //module.Libraries.Add("tritonserver.so");
              } } }
          EOF

          mkdir -p bin/x64/Release/$FRAMEWORKDOT && cp -r ./CppSharp/bin/Release_x64/lib bin/x64/Release/$FRAMEWORKDOT/lib
          LD_PRELOAD=$PWD/CppSharp/bin/Release_x64/libCppSharp.CppParser.so:$PWD/CppSharp/bin/Release_x64/libStd-symbols.so dotnet run -c Release


      - uses: actions/upload-artifact@v4
        with:
          path: |
            variant1/
            variant2/

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 20, 2024

Tried adding ./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h developer_tools/server/include/triton/developer_tools/common.h

to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/server_wrapper.h - getting an error error: no template named 'shared_ptr' in namespace 'std' trying to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/common.h. Does CppSharp support std::shared_ptr? Could it be TypeMap'd? This seems quite a fundamental and a frequent type (especially in modern C++), probably worth supporting it for APIs in core CppSharp...


  ServerOptions(
      const std::vector<std::string>& model_repository_paths,
      const LoggingOptions& logging, const MetricsOptions& metrics,
      const std::vector<BackendConfig>& be_config, const std::string& server_id,
      const std::string& backend_dir, const std::string& repo_agent_dir,
      const bool disable_auto_complete_config,
      const ModelControlMode& model_control_mode,
      const int32_t repository_poll_secs,
      const std::set<std::string>& startup_models,
      const std::vector<RateLimitResource>& rate_limit_resource,
      const int64_t pinned_memory_pool_byte_size,
      const std::vector<CUDAMemoryPoolByteSize>& cuda_memory_pool_byte_size,
      const uint64_t response_cache_byte_size,
      const double& min_cuda_compute_capability, const bool exit_on_error,
      const int32_t exit_timeout_secs,
      const int32_t buffer_manager_thread_count,
      const uint32_t model_load_thread_count,
      const std::vector<ModelLoadGPULimit>& model_load_gpu_limit,
      const std::vector<HostPolicy>& host_policy, std::shared_ptr<Trace> trace);

  InferOptions(
      const std::string& model_name, const int64_t model_version,
      const std::string& request_id, const uint64_t correlation_id,
      const std::string& correlation_id_str, const bool sequence_start,
      const bool sequence_end, const uint64_t priority,
      const uint64_t request_timeout,
      std::shared_ptr<Allocator> custom_allocator,
      std::shared_ptr<Trace> trace);

@vadimkantorov vadimkantorov changed the title [feature request] Complete Github Actions workflow example file with generating bindings of popular libraries (such as ffmpeg or compression libraries) [feature request] Support std::shared_ptr (and complete Github Actions workflow example file with generating bindings of popular libraries) Aug 20, 2024
@HenrikAkseliValve
Copy link
Contributor

HenrikAkseliValve commented Aug 29, 2024

For this case, do I need to do dotnet add package CppSharp? And in both cases, which assemblies do I need to reference for csc.dll to get the basic CppSharp.ILibrary and CppSharp.Driver?

I think these are the main ones:

* CppSharp

* CppSharp.AST

* CppSharp.Generator

* CppSharp.Parser

* CppSharp.Parser.CppSharp

I am not the best person to ask about Nuget as I rarely use it in my workflows.

But development versions are pushed to GitHub packages:

          dotnet nuget push "*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/mono/index.json" --skip-duplicate

https://github.com/mono/CppSharp/pkgs/nuget/CppSharp

The last version says it was published 4 months ago, so maybe publishing for ongoing development commits is not working correctly after all.

I was not able build package via scripts on windows so I made nuspec file which works to get some context... although I'm pretty sure it is dropping lib files at the moment.

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
	<metadata>
		<id>CppSharp</id>
		<version>x.y.z</version>
		<authors>CppSharp Devs</authors>
		<owners>Mono</owners>
		<requireLicenseAcceptance>false</requireLicenseAcceptance>
		<description>YOU!</description>
		<dependencies>
			<dependency id="Microsoft.Win32.Registry" version="5.0.0"/>
		</dependencies>
		<contentFiles>
			<files include="any/any/**/*.h" buildAction="Content" copyToOutput="true" />
		</contentFiles>
	</metadata>
	<files>
		<file src="bin\Release_x64\CppSharp.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.AST.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.Generator.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.Parser.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.CppParser.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.CppParser.lib" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.Parser.CLI.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\CppSharp.Parser.CLI.lib" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\Std-symbols.dll" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\Std-symbols.lib" target="lib\netstandard2.1" />
		<file src="bin\Release_x64\Ijwhost.dll" target="lib\netstandard2.1" />
		<!-- Clang headers which path changes depend upon what version of Clang is downloaded -->
		<!-- Are needed see "Parser/ParserOptions.cs"                                                                      -->
		<file src="build\llvm\llvm-6eb36a-windows-vs2022-x64-RelWithDebInfo\lib\**\include\**\*.h" target="contentFiles\any\any\lib\" />
	</files>
</package>

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 29, 2024

What is CppSharp behavior for binding C++ classes destructors? Does it generate Dispose methods calling the destructor? Does it generate C# finalizers calling Dispose/destructors?

Regarding binding std::shared_ptr<T> - maybe System.Nullable<T> could be somewhat abused to represent std::shared_ptr<T> (might be good as it's a system type always present, so "copies" of this type in bindings of several separately generated bindings are not needed)? Or maybe some new Box<T> or similar could be produced

In modern C++, plenty of various pointer wrappers could now be used in APIs like std::unique_ptr<T> and others... So it's important to have some binding of them (even if not fully performant or requiring additional user's manual intervention to trigger garbage collection / call destructors)

Otherwise, in C# classes have reference/shared_ptr-like semantics anyway, so maybe no wrappers are needed...

@tritao
Copy link
Collaborator

tritao commented Aug 31, 2024

Tried adding ./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h developer_tools/server/include/triton/developer_tools/common.h

to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/server_wrapper.h - getting an error error: no template named 'shared_ptr' in namespace 'std' trying to wrap https://github.com/triton-inference-server/developer_tools/blob/main/server/include/triton/developer_tools/common.h. Does CppSharp support std::shared_ptr?

We do not support shared_ptr, but this error is actually just a general parsing error. That header is not designed to be included on its own, and does not include all its own dependencies, so in this case its just a general C++ issue, would happen with a regular compiler too.

What is CppSharp behavior for binding C++ classes destructors? Does it generate Dispose methods calling the destructor? Does it generate C# finalizers calling Dispose/destructors?

Yes, see the GenerateFinalizers option: https://github.com/mono/CppSharp/blob/345de8b/src/Generator/Options.cs#L125

Regarding binding std::shared_ptr<T> - maybe System.Nullable<T> could be somewhat abused to represent std::shared_ptr<T> (might be good as it's a system type always present, so "copies" of this type in bindings of several separately generated bindings are not needed)? Or maybe some new Box<T> or similar could be produced

We could start by just allowing for manual reference count increase and decrease, which at least would already allow supporting those objects. But the main reason I did not spend too much time with standard library constructs is that it leads to non portable bindings, where you need generated C# bindings code for each ABI, which complicates packaging and distribution on the C# side.

Hence I always recommend modifying the original C++ code, or creating a portable wrapper on top of it. You can check out the Cpp generator type in CppSharp for this task, I have used it before to create a pure C++ wrapper of a complicated C++ library. That in turns was used to generate C# bindings with CppSharp.

@vadimkantorov
Copy link
Author

Thanks for explaining! Deleting common.h from the command gives and succeeds. How does it succeed without shared_ptr support? :)

./CppSharp/bin/Release_x64/CppSharp.CLI -m tritondevelopertoolsserver -g csharp -p linux -a x64 -o ./variant3/ -I=developer_tools/server/include -I=core/include -I=developer_tools/server/include/triton/developer_tools developer_tools/server/include/triton/developer_tools/server_wrapper.h developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h
Generating C# bindings for Linux x64...
Parsing libraries...
Parsing code...
Parsed '/home/runner/work/tritonservercppsharp/tritonservercppsharp/developer_tools/server/include/triton/developer_tools/server_wrapper.h, /home/runner/work/tritonservercppsharp/tritonservercppsharp/developer_tools/server/include/triton/developer_tools/generic_server_wrapper.h'
Processing code...
Generating code...
Generated 'Std.cs'
Generated 'developer_tools.cs'

I think for bindings not distributed publicly but generated, compiled and consumed on the target platform, it is okay to support non-ABI-portable things like shared_ptr. For reference, https://github.com/triton-inference-server/server/blob/main/docs/customization_guide/inference_protocols.md#java-bindings-for-in-process-triton-server-api also distribute these Java bindings (although do not recommend using them) to these same C++ code: https://github.com/bytedeco/javacpp-presets/tree/master/tritonserver/src/gen/java/org/bytedeco/tritonserver/tritondevelopertoolsserver

So overall, JavaCpp seems to support shared_ptr: bytedeco/javacpp#623

Maybe for CppSharp, the model of a single repo with GitHub Actions - i.e. JavaCpp presets repo: https://github.com/bytedeco/javacpp-presets, reproducbile bindings generation could also be very useful: https://github.com/bytedeco/javacpp-presets

@tritao
Copy link
Collaborator

tritao commented Aug 31, 2024

Thanks for explaining! Deleting common.h from the command gives and succeeds. How does it succeed without shared_ptr support? :)

It will ignore any methods and fields that are not supported, so the binding can still be generated.

I think for bindings not distributed publicly but generated, compiled and consumed on the target platform, it is okay to support non-ABI-portable things like shared_ptr. For reference, https://github.com/triton-inference-server/server/blob/main/docs/customization_guide/inference_protocols.md#java-bindings-for-in-process-triton-server-api also distribute these Java bindings (although do not recommend using them) to these same C++ code: https://github.com/bytedeco/javacpp-presets/tree/master/tritonserver/src/gen/java/org/bytedeco/tritonserver/tritondevelopertoolsserver

So overall, JavaCpp seems to support shared_ptr: bytedeco/javacpp#623

They support it by generating C++ code (with JNI) which is a lot more doable for C++ standard library constructs.
And somewhat equivalent to what I said before about generating pure C++ bindings with the Cpp generator in CppSharp.

With the regular CppSharp approach, it only generates C++ code for inline symbols for which there is absolute no other way.
We currently support std::string by drilling down into the templates from the standard library implementation and having specific code for that: https://github.com/mono/CppSharp/blob/main/src/Generator/Types/Std/Stdlib.CSharp.cs#L304

Its doable to do the same for other C++ std lib types, but overall its somewhat complicated and error prone.
I'd probably switch to the approach of generating supporting C++ code, helper functions to wrap std:: types, which would make it much easier to extend and support all of C++ more easily.

Maybe for CppSharp, the model of a single repo with GitHub Actions - i.e. JavaCpp presets repo: https://github.com/bytedeco/javacpp-presets, reproducbile bindings generation could also be very useful: https://github.com/bytedeco/javacpp-presets

No doubt, this would be great, was always on my mind, but its a lot of work to setup and maintain, so unless someone else is willing to do the dirty work, its not going to happen from my side.

@vadimkantorov
Copy link
Author

vadimkantorov commented Aug 31, 2024

We currently support std::string by drilling down into the templates from the standard library implementation and having specific code for that:

Maybe then an example/recipe in the docs for adding non-portable support for shared_ptr via some hacks (since C# reference types already have some sort of shared_ptr semantics already) and showcase TypeMap... For the user's particular platform/compiler/libstdc++.

No doubt, this would be great, was always on my mind, but its a lot of work to setup and maintain

Maybe if it's not to support a high-quality bar and just be a place where people contribute single-file, self-contained GitHub Actions workflow files as examples, then the maintenance bar would be lower and some reproducibility would be preserved. And also might be nice if https://github.com/dotnet org or https://dotnetfoundation.org/ sponsored/supported this effort...

They support it by generating C++ code (with JNI) which is a lot more doable for C++ standard library constructs. And somewhat equivalent to what I said before about generating pure C++ bindings with the Cpp generator in CppSharp.
With the regular CppSharp approach, it only generates C++ code for inline symbols for which there is absolute no other way.

But yeah, I see what you mean...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants