btzy / nativefiledialog-extended

Cross platform (Windows, Mac, Linux) native file dialog library with C and C++ bindings, based on mlabbe/nativefiledialog.
zlib License
598 stars 89 forks source link

I made a C# binding #125

Closed TheAirBlow closed 5 months ago

TheAirBlow commented 6 months ago

You can check it out here. Please update the wiki page with language bindings:

This page lists known bindings in other programming languages.  Please report issues with these bindings on their respective repositories.

| Language     | Repository                                                                            |
| ------------ | ------------------------------------------------------------------------------------- |
| Rust         | [nfde-rs](https://github.com/btzy/nfde-rs)                                            |
| Java/Kotlin  | [Native File Dialog Java](https://github.com/WonderzGmbH/nativefiledialog-java)       |
| Java         | [LWJGL - Lightweight Java Game Library 3](https://github.com/LWJGL/lwjgl3)            |
| C#           | [NativeFileDialog.Extended](https://github.com/TheAirBlow/NativeFileDialog.Extended)  |
btzy commented 5 months ago

Thanks for the interest in NFD. @ds5678 is also in the process of building https://github.com/Speykious/NativeFileDialogs.NET.

As the wiki is only editable by me, putting a link there confers the linked repo some amount of implicit endorsement, and I'm more comfortable with the other repo since it is built from source and is more complete (it contains the examples too).

Also, does your repo work with Mono? I see libnfd.so, which is a Linux binary...?

TheAirBlow commented 5 months ago

Thanks for the interest in NFD. @ds5678 is also in the process of building https://github.com/Speykious/NativeFileDialogs.NET.

As the wiki is only editable by me, putting a link there confers the linked repo some amount of implicit endorsement, and I'm more comfortable with the other repo since it is built from source and is more complete (it contains the examples too).

Also, does your repo work with Mono? I see libnfd.so, which is a Linux binary...?

Yeah, it probably won't because it's built for .NET 7, can be fixed though. The binaries, I just downloaded them off the latest GitHub actions build. It currently supports Linux, MacOS and Windows, but x64 only.

Adding both the U8 and N methods wouldn't take much effort to be honest, may do it later so it would be complete. Built from source? That isn't really necessary at all because the library is really small and the APIs aren't supposed to change. Not just that it's unecessary, it's a lot more annoying to use and it's also quite bloated for no reason. Just compare this and this.

On another note: it would be a good idea to have a push/pull system like he does.

btzy commented 5 months ago

It currently supports Linux, MacOS and Windows, but x64 only.

I don't know much about C#. How do you run this on Linux and MacOS without Mono?

TheAirBlow commented 5 months ago

It currently supports Linux, MacOS and Windows, but x64 only. I don't know much about C#. How do you run this on Linux and MacOS without Mono?

Your understanding of .NET is quite outdated, so here's a quick explanation: .NET Framework is what you are referring about, and it's windows only. Mono is a cross-platform runtime for it. .NET Core is the first official cross-platform solution, but is now deprecated. .NET is where it is now, with the latest stable version being .NET 7.

On another note - a library can target multiple versions, like if you target .NET Standard 2.0 it would catch basically all of the latest versions (and a lot of old ones too) of .NET Framework, Mono, .NET Core and the newer .NET.

TheAirBlow commented 5 months ago

Mono can only run .NET Framework, because it is it's indended purpose - to be a runtime for an otherwise windows-only thing. .NET Core and the new .NET are the official take at cross-platform, and applications compiled to target them cannot be run by Mono.

btzy commented 5 months ago

Built from source? That isn't really necessary at all because the library is really small and the APIs aren't supposed to change.

I think it's more that people should exercise caution when downloading prebuilt binaries from an unknown source.

Not just that it's unecessary, it's a lot more annoying to use and it's also quite bloated for no reason. Just compare this and this.

Well, it's autogenerated so that's kind of expected, but yeah I agree it's a lot more bloated.

TheAirBlow commented 5 months ago

I misunderstood what you meant by "built from source", I though you were talking about code generation, so sorry for that.

btzy commented 5 months ago

Thanks for the explanation on .NET. I last seriously worked on C# more than 10 years ago.

TheAirBlow commented 5 months ago

It should be possible to set up CI in a way that would download the latest binaries from an official source and then build the NuGet package afterwards, or build from source like you said.

btzy commented 5 months ago

On another note: it would be a good idea to have a push/pull system like he does.

Can you clarify what a push/pull system is?

TheAirBlow commented 5 months ago

On another note: it would be a good idea to have a push/pull system like he does.

Can you clarify what a push/pull system is?

I am referring to NfdManager.cs, but now I have realized that from what I know, this library requires you to initialize on every thread instead of doing it once on any thread or something, so it's flawed? Correct me if I'm wrong, otherwise it is a good solution to initialize and quit when necessary.

ds5678 commented 5 months ago

the latest stable version being .NET 7

.NET versions are released every November, so the latest is actually 8.

TheAirBlow commented 5 months ago

the latest stable version being .NET 7

.NET versions are released every November, so the latest is actually 8.

Yeah, I know that, but isn't it preview? I said latest stable. P.S. I missed it, oops xD

ds5678 commented 5 months ago

LTS

ds5678 commented 5 months ago

Even numbered .NET versions get long term support.

.NET 9 is currently in preview.

btzy commented 5 months ago

On another note: it would be a good idea to have a push/pull system like he does.

Can you clarify what a push/pull system is?

I am referring to NfdManager.cs, but now I have realized that from what I know, this library requires you to initialize on every thread instead of doing it once on any thread or something, so it's flawed? Correct me if I'm wrong, otherwise it is a good solution to initialize and quit when necessary.

NFD isn't really intended to be invoked from multiple threads, and AFAIK MacOS at least doesn't like it if you do UI-related things from another thread.

TheAirBlow commented 5 months ago

Even numbered .NET versions get long term support.

.NET 9 is currently in preview.

Actually I remember seeing that it was released, but the arch repos were stuck at .NET 7 for a long time, so I completely forgot about it.

TheAirBlow commented 5 months ago

On another note: it would be a good idea to have a push/pull system like he does.

Can you clarify what a push/pull system is?

I am referring to NfdManager.cs, but now I have realized that from what I know, this library requires you to initialize on every thread instead of doing it once on any thread or something, so it's flawed? Correct me if I'm wrong, otherwise it is a good solution to initialize and quit when necessary.

NFD isn't really intended to be invoked from multiple threads, and AFAIK MacOS at least doesn't like it if you do UI-related things from another thread.

So is just doing Init right before opening a dialog, and then promptly quitting is fine? I am attempting to make it as easy to use without all the stupidity of unmanaged.

btzy commented 5 months ago

On another note: it would be a good idea to have a push/pull system like he does.

Can you clarify what a push/pull system is?

I am referring to NfdManager.cs, but now I have realized that from what I know, this library requires you to initialize on every thread instead of doing it once on any thread or something, so it's flawed? Correct me if I'm wrong, otherwise it is a good solution to initialize and quit when necessary.

NFD isn't really intended to be invoked from multiple threads, and AFAIK MacOS at least doesn't like it if you do UI-related things from another thread.

So is just doing Init right before opening a dialog, and then promptly quitting is fine?

Yes, that is fine. You should still only call NFD functions from your UI thread though.

TheAirBlow commented 5 months ago

So, from what I understand, I need to do the following:

Also, is it normal than on a UTF-8 system like Linux, UTF-16 implementations would output garbage or it is me goofing up marshaling?

ds5678 commented 5 months ago

I mark the native methods using platform guards in my bindings, so that the IDE warns users that they should only use them on Windows.

btzy commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

ds5678 commented 5 months ago

.NET supports both UTF-16 and UTF-8 in source code. Other encodings (like Ascii) have library support.

TheAirBlow commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

I am talking about marshaling - the process of conversion between managed and unmanaged types. According to the docs, by default it marshals strings from "A pointer to a null-terminated array of ANSI characters"

btzy commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

I am talking about marshaling - the process of conversion between managed and unmanaged types. According to the docs, by default it marshals strings from "A pointer to a null-terminated array of ANSI characters."

It seems that BSTR is eventually typedef'd to wchar* on Windows (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr), though I couldn't find anything about Linux/Ubuntu. If it's also typedef'd to wchar* on Unix-like systems, then that isn't going to work automatically, right?

TheAirBlow commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

I am talking about marshaling - the process of conversion between managed and unmanaged types. According to the docs, by default it marshals strings from "A pointer to a null-terminated array of ANSI characters."

It seems that BSTR is eventually typedef'd to wchar on Windows (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr), though I couldn't find anything about Linux/Ubuntu. If it's also typedef'd to wchar on Unix-like systems, then that isn't going to work automatically, right?

I edited it. The first table is unrelated - look at the second one. And BSTR may be typedef'd, but it still is length-prefixed as per the docs.

btzy commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

I am talking about marshaling - the process of conversion between managed and unmanaged types. According to the docs, by default it marshals strings from "A pointer to a null-terminated array of ANSI characters."

It seems that BSTR is eventually typedef'd to wchar on Windows (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr), though I couldn't find anything about Linux/Ubuntu. If it's also typedef'd to wchar on Unix-like systems, then that isn't going to work automatically, right?

I edited it. The first table is unrelated - look at the second one. And BSTR may be typedef'd, but it still is length-prefixed as per the docs.

Yeah, but the NFD U8/N functions on Linux and Mac expect UTF-8 strings, while after stripping the length prefix, it seems that the BSTR still contains wchar strings?

TheAirBlow commented 5 months ago

I think making it build from source would be beneficial. I don't really have an opinion about targeting .NET or .NET Standard, since I don't know much about it. If .NET is what you originally intended, I'm fine with sticking with it.

Implement both U8 and N (but automatically select one or the other based on the OS)

Does .NET use different string encoding depending on the OS? The documentation seems to say that it uses UTF-16 code units. Do you mean you're going to implement conversion from UTF-16 to UTF-8 for Mac and Linux in C# land?

I am talking about marshaling - the process of conversion between managed and unmanaged types. According to the docs, by default it marshals strings from "A pointer to a null-terminated array of ANSI characters."

It seems that BSTR is eventually typedef'd to wchar on Windows (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr), though I couldn't find anything about Linux/Ubuntu. If it's also typedef'd to wchar on Unix-like systems, then that isn't going to work automatically, right?

I edited it. The first table is unrelated - look at the second one. And BSTR may be typedef'd, but it still is length-prefixed as per the docs.

Yeah, but the NFD U8/N functions on Linux and Mac expect UTF-8 strings, while after stripping the length prefix, it seems that the BSTR still contains wchar strings?

It does, but again, both of us are looking at the wrong thing. I edited my original message - by default it marshals to a char* type with ANSI characters.

TheAirBlow commented 5 months ago

Ok, I finished now, it's built from source.

btzy commented 5 months ago

Thanks! I've added it to the wiki page: https://github.com/btzy/nativefiledialog-extended/wiki/Bindings-in-other-languages

ds5678 commented 5 months ago

@ds5678 is also in the process of building

To be clear, this is more-or-less done. My changes to that repository have been available on the owner's NuGet for about a week now.

btzy commented 5 months ago

@ds5678 is also in the process of building

To be clear, this is more-or-less done. My changes to that repository have been available on the owner's NuGet for about a week now.

Thanks, I've added NativeFileDialogs.NET to the list too.