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

Double pointers to strings have no NativeTypeInfo #241

Closed
timsneath opened this issue Feb 16, 2021 · 8 comments
Closed

Double pointers to strings have no NativeTypeInfo #241

timsneath opened this issue Feb 16, 2021 · 8 comments
Labels
usability Touch-up to improve the user experience for a language projection

Comments

@timsneath
Copy link
Contributor

timsneath commented Feb 16, 2021

ShGetKnownFolderPath returns a Pointer<Pointer<Utf16>> in my existing (non-metadata based) projection, but the Win32 metadata shows it as returning a Pointer<Pointer<Uint16>> because there's no NativeTypeInfo attribute for ppszPath.

HRESULT SHGetKnownFolderPath(
  REFKNOWNFOLDERID rfid,
  DWORD            dwFlags,
  HANDLE           hToken,
  PWSTR            *ppszPath
);

ILSpy:

[DllImport("SHELL32", ExactSpelling = true)]
public unsafe static extern HRESULT SHGetKnownFolderPath(
  [In][Const] Guid* rfid, 
  [In] uint dwFlags, 
  [Optional][In] HANDLE hToken, 
  [Out] ushort** ppszPath);
@kennykerr
Copy link
Contributor

It might be better if we added a first-class WCHAR type rather than relying on ushort plus an attribute. That would seem to be a lot simpler given how ubiquitous such pointer types are. Just a thought.

@sotteson1
Copy link
Contributor

I've been thinking the same thing. The problem is not all WCHAR* are null terminated, although most are. And some are double null terminated. We have the same problem with single byte strings too. I could follow our handle pattern for these and use attributes if they're not normal null-terminated strings.

@timsneath
Copy link
Contributor Author

I suspect we can have our cake and eat it. WCHAR is a good general type for Unicode string types, but we can use attributes to more finely delineate between subtypes.

I'm also wondering (but haven't checked) how we delineate between UTF-8 and ANSI strings, which might both be represented as Pointer<Utf8> in a Dart projection, but are different in that only UTF-8 allows variable length encoding.

@AArnott
Copy link
Member

AArnott commented Feb 16, 2021

We should not create typedef structs where equivalent ECMA types already exist. We should just use System.Char here.

@AArnott
Copy link
Member

AArnott commented Feb 16, 2021

Attributes to identify additional traits such as null-termination are fine, but we don't need a custom struct instead of char to represent the data type pointed to.

@kennykerr
Copy link
Contributor

There's a big difference between a char and a LPCWSTR. The latter implies a null terminated string of 16 bit characters. Having a single handle type for LPCWSTR is helpful in avoiding having to always express a pointer to a character that's constant and terminated.

Also, WinRT metadata already reserves ECMA char and string to mean a WinRT character and string respectively. These are different to LPCWSTR and would make it impossible for language projections to deal with both WinRT and Win32 metadata at the same time.

@sotteson1
Copy link
Contributor

sotteson1 commented Feb 16, 2021

I'm suggesting we change strings to look like this:

[NativeTypedef]
public struct PWSTR
{
    public char* Value;
}
 
[NativeTypedef]
public struct PSTR
{
    public byte* Value;
}

And then use attributes for things like const or non-null terminated.

@mikebattista mikebattista added the usability Touch-up to improve the user experience for a language projection label Feb 16, 2021
@sotteson1
Copy link
Contributor

Fixed in latest release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
usability Touch-up to improve the user experience for a language projection
Projects
None yet
Development

No branches or pull requests

5 participants