From e8bf894c31ab52f62a132fbd82e3335f73cb8eee Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 19 Apr 2021 11:54:43 -0400 Subject: [PATCH 1/5] Try to fix use of C long in TTF_FontFaces --- src/SDL2_ttf.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SDL2_ttf.cs b/src/SDL2_ttf.cs index 13e3818..d1005e5 100644 --- a/src/SDL2_ttf.cs +++ b/src/SDL2_ttf.cs @@ -208,9 +208,11 @@ namespace SDL2 [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] public static extern void TTF_SetFontKerning(IntPtr font, int allowed); - /* font refers to a TTF_Font* */ + /* font refers to a TTF_Font*. + * IntPtr is actually a C long! This ignores Win64! + */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] - public static extern long TTF_FontFaces(IntPtr font); + public static extern IntPtr TTF_FontFaces(IntPtr font); /* font refers to a TTF_Font* */ [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] From fadd0135c33f7b9ef55b70c4cc4cca5af7264751 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 19 Apr 2021 11:57:58 -0400 Subject: [PATCH 2/5] Removed obsolete Roadmap section from README --- README | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README b/README index 05e5d75..c220f52 100644 --- a/README +++ b/README @@ -40,9 +40,3 @@ names threads with the 0x406D1388 exception will silently exit. To prevent this exception from being thrown by SDL, add this line before your SDL_Init call: SDL.SDL_SetHint(SDL.SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1"); - -Roadmap -------- -To see the current roadmap for SDL2#, visit the GitHub issues page: - -https://github.com/flibitijibibo/SDL2-CS/issues From a234470e39d32a071ee92f5888774930de2b5c0d Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sat, 15 May 2021 09:10:02 -0400 Subject: [PATCH 3/5] Make all UTF8 conversions nullable. Trying to avoid null strings was far too invasive and kept creating bugs in the wrapper, and the wrapper should not have enough code to create bugs in the first place. --- src/SDL2.cs | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/SDL2.cs b/src/SDL2.cs index 13645cf..b76e6b4 100644 --- a/src/SDL2.cs +++ b/src/SDL2.cs @@ -47,24 +47,10 @@ namespace SDL2 /* Used for stack allocated string marshaling. */ internal static int Utf8Size(string str) - { - Debug.Assert(str != null); - return (str.Length * 4) + 1; - } - internal static int Utf8SizeNullable(string str) { return str != null ? (str.Length * 4) + 1 : 0; } internal static unsafe byte* Utf8Encode(string str, byte* buffer, int bufferSize) - { - Debug.Assert(str != null); - fixed (char* strPtr = str) - { - Encoding.UTF8.GetBytes(strPtr, str.Length + 1, buffer, bufferSize); - } - return buffer; - } - internal static unsafe byte* Utf8EncodeNullable(string str, byte* buffer, int bufferSize) { if (str == null) { @@ -1234,16 +1220,16 @@ namespace SDL2 string message, IntPtr window ) { - int utf8TitleBufSize = Utf8SizeNullable(title); + int utf8TitleBufSize = Utf8Size(title); byte* utf8Title = stackalloc byte[utf8TitleBufSize]; - int utf8MessageBufSize = Utf8SizeNullable(message); + int utf8MessageBufSize = Utf8Size(message); byte* utf8Message = stackalloc byte[utf8MessageBufSize]; return INTERNAL_SDL_ShowSimpleMessageBox( flags, - Utf8EncodeNullable(title, utf8Title, utf8TitleBufSize), - Utf8EncodeNullable(message, utf8Message, utf8MessageBufSize), + Utf8Encode(title, utf8Title, utf8TitleBufSize), + Utf8Encode(message, utf8Message, utf8MessageBufSize), window ); } @@ -1497,10 +1483,10 @@ namespace SDL2 int h, SDL_WindowFlags flags ) { - int utf8TitleBufSize = Utf8SizeNullable(title); + int utf8TitleBufSize = Utf8Size(title); byte* utf8Title = stackalloc byte[utf8TitleBufSize]; return INTERNAL_SDL_CreateWindow( - Utf8EncodeNullable(title, utf8Title, utf8TitleBufSize), + Utf8Encode(title, utf8Title, utf8TitleBufSize), x, y, w, h, flags ); @@ -1822,7 +1808,7 @@ namespace SDL2 ); public static unsafe SDL_bool SDL_GL_ExtensionSupported(string extension) { - int utf8ExtensionBufSize = Utf8SizeNullable(extension); + int utf8ExtensionBufSize = Utf8Size(extension); byte* utf8Extension = stackalloc byte[utf8ExtensionBufSize]; return INTERNAL_SDL_GL_ExtensionSupported( Utf8Encode(extension, utf8Extension, utf8ExtensionBufSize) @@ -8106,16 +8092,16 @@ namespace SDL2 ); public static unsafe string SDL_GetPrefPath(string org, string app) { - int utf8OrgBufSize = Utf8SizeNullable(org); + int utf8OrgBufSize = Utf8Size(org); byte* utf8Org = stackalloc byte[utf8OrgBufSize]; - int utf8AppBufSize = Utf8SizeNullable(app); + int utf8AppBufSize = Utf8Size(app); byte* utf8App = stackalloc byte[utf8AppBufSize]; return UTF8_ToManaged( INTERNAL_SDL_GetPrefPath( - Utf8EncodeNullable(org, utf8Org, utf8OrgBufSize), - Utf8EncodeNullable(app, utf8App, utf8AppBufSize) + Utf8Encode(org, utf8Org, utf8OrgBufSize), + Utf8Encode(app, utf8App, utf8AppBufSize) ), true ); From e316ae5cfdbc4e604fdca305c0932f3728059bc9 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sat, 15 May 2021 09:47:28 -0400 Subject: [PATCH 4/5] Give the heap-allocated Utf8Encode a unique function name --- src/SDL2.cs | 20 ++++++++++---------- src/SDL2_image.cs | 10 +++++----- src/SDL2_mixer.cs | 6 +++--- src/SDL2_ttf.cs | 20 ++++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/SDL2.cs b/src/SDL2.cs index b76e6b4..fd85e7a 100644 --- a/src/SDL2.cs +++ b/src/SDL2.cs @@ -66,7 +66,7 @@ namespace SDL2 /* Used for heap allocated string marshaling. * Returned byte* must be free'd with FreeHGlobal. */ - internal static unsafe byte* Utf8Encode(string str) + internal static unsafe byte* Utf8EncodeHeap(string str) { Debug.Assert(str != null); int bufferSize = Utf8Size(str); @@ -237,8 +237,8 @@ namespace SDL2 string file, string mode ) { - byte* utf8File = Utf8Encode(file); - byte* utf8Mode = Utf8Encode(mode); + byte* utf8File = Utf8EncodeHeap(file); + byte* utf8Mode = Utf8EncodeHeap(mode); IntPtr rwOps = INTERNAL_SDL_RWFromFile( utf8File, utf8Mode @@ -372,7 +372,7 @@ namespace SDL2 private static extern unsafe IntPtr INTERNAL_SDL_LoadFile(byte* file, out IntPtr datasize); public static unsafe IntPtr SDL_LoadFile(string file, out IntPtr datasize) { - byte* utf8File = Utf8Encode(file); + byte* utf8File = Utf8EncodeHeap(file); IntPtr result = INTERNAL_SDL_LoadFile(utf8File, out datasize); Marshal.FreeHGlobal((IntPtr) utf8File); return result; @@ -1777,7 +1777,7 @@ namespace SDL2 private static extern unsafe int INTERNAL_SDL_GL_LoadLibrary(byte* path); public static unsafe int SDL_GL_LoadLibrary(string path) { - byte* utf8Path = Utf8Encode(path); + byte* utf8Path = Utf8EncodeHeap(path); int result = INTERNAL_SDL_GL_LoadLibrary( utf8Path ); @@ -2152,7 +2152,7 @@ namespace SDL2 ); public static unsafe int SDL_Vulkan_LoadLibrary(string path) { - byte* utf8Path = Utf8Encode(path); + byte* utf8Path = Utf8EncodeHeap(path); int result = INTERNAL_SDL_Vulkan_LoadLibrary( utf8Path ); @@ -4378,7 +4378,7 @@ namespace SDL2 public static unsafe int SDL_SetClipboardText( string text ) { - byte* utf8Text = Utf8Encode(text); + byte* utf8Text = Utf8EncodeHeap(text); int result = INTERNAL_SDL_SetClipboardText( utf8Text ); @@ -6507,7 +6507,7 @@ namespace SDL2 public static unsafe int SDL_GameControllerAddMapping( string mappingString ) { - byte* utf8MappingString = Utf8Encode(mappingString); + byte* utf8MappingString = Utf8EncodeHeap(mappingString); int result = INTERNAL_SDL_GameControllerAddMapping( utf8MappingString ); @@ -7902,7 +7902,7 @@ namespace SDL2 public static unsafe SDL_bool SDL_AndroidRequestPermission( string permission ) { - byte* permissionPtr = Utf8Encode(permission); + byte* permissionPtr = Utf8EncodeHeap(permission); SDL_bool result = INTERNAL_SDL_AndroidRequestPermission( permissionPtr ); @@ -8225,7 +8225,7 @@ namespace SDL2 private static unsafe extern int INTERNAL_SDL_OpenURL(byte* url); public static unsafe int SDL_OpenURL(string url) { - byte* urlPtr = Utf8Encode(url); + byte* urlPtr = Utf8EncodeHeap(url); int result = INTERNAL_SDL_OpenURL(urlPtr); Marshal.FreeHGlobal((IntPtr) urlPtr); return result; diff --git a/src/SDL2_image.cs b/src/SDL2_image.cs index c2b9a56..0afec65 100644 --- a/src/SDL2_image.cs +++ b/src/SDL2_image.cs @@ -94,7 +94,7 @@ namespace SDL2 ); public static unsafe IntPtr IMG_Load(string file) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); IntPtr handle = INTERNAL_IMG_Load( utf8File ); @@ -142,7 +142,7 @@ namespace SDL2 IntPtr renderer, string file ) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); IntPtr handle = INTERNAL_IMG_LoadTexture( renderer, utf8File @@ -181,7 +181,7 @@ namespace SDL2 int freesrc, string type ) { - byte* utf8Type = SDL.Utf8Encode(type); + byte* utf8Type = SDL.Utf8EncodeHeap(type); IntPtr handle = INTERNAL_IMG_LoadTextureTyped_RW( renderer, src, @@ -207,7 +207,7 @@ namespace SDL2 ); public static unsafe int IMG_SavePNG(IntPtr surface, string file) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); int result = INTERNAL_IMG_SavePNG( surface, utf8File @@ -234,7 +234,7 @@ namespace SDL2 ); public static unsafe int IMG_SaveJPG(IntPtr surface, string file, int quality) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); int result = INTERNAL_IMG_SaveJPG( surface, utf8File, diff --git a/src/SDL2_mixer.cs b/src/SDL2_mixer.cs index 5b94c1f..e98c91d 100644 --- a/src/SDL2_mixer.cs +++ b/src/SDL2_mixer.cs @@ -205,7 +205,7 @@ namespace SDL2 ); public static unsafe IntPtr Mix_LoadMUS(string file) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); IntPtr handle = INTERNAL_Mix_LoadMUS( utf8File ); @@ -579,7 +579,7 @@ namespace SDL2 ); public static unsafe int Mix_SetMusicCMD(string command) { - byte* utf8Cmd = SDL.Utf8Encode(command); + byte* utf8Cmd = SDL.Utf8EncodeHeap(command); int result = INTERNAL_Mix_SetMusicCMD( utf8Cmd ); @@ -599,7 +599,7 @@ namespace SDL2 ); public static unsafe int Mix_SetSoundFonts(string paths) { - byte* utf8Paths = SDL.Utf8Encode(paths); + byte* utf8Paths = SDL.Utf8EncodeHeap(paths); int result = INTERNAL_Mix_SetSoundFonts( utf8Paths ); diff --git a/src/SDL2_ttf.cs b/src/SDL2_ttf.cs index d1005e5..ba91c7f 100644 --- a/src/SDL2_ttf.cs +++ b/src/SDL2_ttf.cs @@ -101,7 +101,7 @@ namespace SDL2 ); public static unsafe IntPtr TTF_OpenFont(string file, int ptsize) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); IntPtr handle = INTERNAL_TTF_OpenFont( utf8File, ptsize @@ -131,7 +131,7 @@ namespace SDL2 int ptsize, long index ) { - byte* utf8File = SDL.Utf8Encode(file); + byte* utf8File = SDL.Utf8EncodeHeap(file); IntPtr handle = INTERNAL_TTF_OpenFontIndex( utf8File, ptsize, @@ -302,7 +302,7 @@ namespace SDL2 out int w, out int h ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); int result = INTERNAL_TTF_SizeUTF8( font, utf8Text, @@ -354,7 +354,7 @@ namespace SDL2 out int extent, out int count ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); int result = INTERNAL_TTF_MeasureUTF8( font, utf8Text, @@ -400,7 +400,7 @@ namespace SDL2 string text, SDL.SDL_Color fg ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Solid( font, utf8Text, @@ -447,7 +447,7 @@ namespace SDL2 SDL.SDL_Color fg, uint wrapLength ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Solid_Wrapped( font, utf8Text, @@ -512,7 +512,7 @@ namespace SDL2 SDL.SDL_Color fg, SDL.SDL_Color bg ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Shaded( font, utf8Text, @@ -562,7 +562,7 @@ namespace SDL2 SDL.SDL_Color bg, uint wrapLength ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Shaded_Wrapped( font, utf8Text, @@ -626,7 +626,7 @@ namespace SDL2 string text, SDL.SDL_Color fg ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Blended( font, utf8Text, @@ -669,7 +669,7 @@ namespace SDL2 SDL.SDL_Color fg, uint wrapped ) { - byte* utf8Text = SDL.Utf8Encode(text); + byte* utf8Text = SDL.Utf8EncodeHeap(text); IntPtr result = INTERNAL_TTF_RenderUTF8_Blended_Wrapped( font, utf8Text, From 00c94a24eba43ba0fb1c3efc7adf72f87b584999 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sat, 15 May 2021 09:58:00 -0400 Subject: [PATCH 5/5] Allow Utf8EncodeHeap to return NULL, clean up Utf8Size --- src/SDL2.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/SDL2.cs b/src/SDL2.cs index fd85e7a..71af7f7 100644 --- a/src/SDL2.cs +++ b/src/SDL2.cs @@ -48,7 +48,11 @@ namespace SDL2 /* Used for stack allocated string marshaling. */ internal static int Utf8Size(string str) { - return str != null ? (str.Length * 4) + 1 : 0; + if (str == null) + { + return 0; + } + return (str.Length * 4) + 1; } internal static unsafe byte* Utf8Encode(string str, byte* buffer, int bufferSize) { @@ -68,7 +72,11 @@ namespace SDL2 */ internal static unsafe byte* Utf8EncodeHeap(string str) { - Debug.Assert(str != null); + if (str == null) + { + return (byte*) 0; + } + int bufferSize = Utf8Size(str); byte* buffer = (byte*) Marshal.AllocHGlobal(bufferSize); fixed (char* strPtr = str)