From 09ac12bc485abac2c1048a760449b7f98620c62b Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 16 Jun 2020 04:35:48 +0300 Subject: [PATCH] Partially (const wchar_t*) support wide strings Signed-off-by: Dimitar Dobrev --- src/Generator/Types/Std/Stdlib.cs | 22 +++++++++++++-------- tests/CSharp/CSharp.Tests.cs | 33 +++++++++++++++++++++++++++++++ tests/CSharp/CSharp.cpp | 6 ++++++ tests/CSharp/CSharp.h | 2 ++ 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/Generator/Types/Std/Stdlib.cs b/src/Generator/Types/Std/Stdlib.cs index 0aaffb95..192a9fe8 100644 --- a/src/Generator/Types/Std/Stdlib.cs +++ b/src/Generator/Types/Std/Stdlib.cs @@ -149,20 +149,23 @@ namespace CppSharp.Types.Std if (ctx.Kind == TypePrinterContextKind.Managed) return new CILType(typeof(string)); - if (ctx.Parameter == null || ctx.Parameter.Name == Helpers.ReturnIdentifier) + bool isWStr; + if (ctx.Parameter == null || ctx.Parameter.Name == Helpers.ReturnIdentifier || + (isWStr = ctx.Parameter.Type.Desugar().IsPointerToPrimitiveType(PrimitiveType.WideChar) && + Context.TargetInfo.WCharWidth > 16)) { var typePrinter = new CSharpTypePrinter(Context); return new CustomType(typePrinter.IntPtrType); } + if (Context.Options.Encoding == Encoding.Unicode || + Context.Options.Encoding == Encoding.BigEndianUnicode || isWStr) + return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"); + if (Context.Options.Encoding == Encoding.ASCII || Context.Options.Encoding == Encoding.UTF8) return new CustomType("[MarshalAs(UnmanagedType.LPUTF8Str)] string"); - if (Context.Options.Encoding == Encoding.Unicode || - Context.Options.Encoding == Encoding.BigEndianUnicode) - return new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"); - throw new System.NotSupportedException( $"{Context.Options.Encoding.EncodingName} is not supported yet."); } @@ -170,12 +173,15 @@ namespace CppSharp.Types.Std public override void CSharpMarshalToNative(CSharpMarshalContext ctx) { string param = ctx.Parameter.Name; + Type type = ctx.Parameter.Type.Desugar(resolveTemplateSubstitution: false); if (ctx.Parameter.Usage == ParameterUsage.Unknown && - !ctx.Parameter.Type.IsReference() && - !(ctx.Parameter.Type is TemplateParameterSubstitutionType) && + !type.IsReference() && + !(type is TemplateParameterSubstitutionType) && ctx.MarshalKind != MarshalKind.NativeField && ctx.MarshalKind != MarshalKind.VTableReturnValue && - ctx.MarshalKind != MarshalKind.Variable) + ctx.MarshalKind != MarshalKind.Variable && + (!type.IsPointerToPrimitiveType(PrimitiveType.WideChar) || + Context.TargetInfo.WCharWidth == 16)) { ctx.Return.Write(param); return; diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index f2f0fc60..04ca98ed 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -1389,6 +1389,39 @@ public unsafe class CSharpTests : GeneratorTestFixture } } + [Test] + public void TestWideString() + { + var strings = new[] { "ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + + "ѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩ" + + "ҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӏӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹӺӻӼӽ" + + "ӾӿԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԐԑԒԓ", + + "აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶჷჸჹჺ", + + "ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖՙաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև", + + "々〆〱〲〳〴〵〻〼ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづて" + + "でとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕ" + + "ゖゝゞゟァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニ" + + "ヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ" + + "ーヽヾヿㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ", + + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzªµºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ" + + "ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵ" + + "ĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊ" + + "ƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝ" + + "ǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳ" + + "ȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽ" + + "ḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚ" + + "ẛẞẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹ" + + "ⱠⱡⱢⱣⱤⱥⱦⱧⱨⱩⱪⱫⱬⱭⱱⱲⱳⱴⱵⱶⱷ" }; + foreach (var @string in strings) + { + Assert.That(CSharp.CSharp.TakeReturnWideString(@string), Is.EqualTo(@string)); + } + } + [Test] public void TestImplicitConversionToString() { diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index 0e0cfe44..cb955511 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -1693,6 +1693,12 @@ const Foo*& takeReturnReferenceToPointer(const Foo*& foo) return foo; } +const wchar_t* takeReturnWideString(const wchar_t* wideString) +{ + WideString = wideString; + return WideString.data(); +} + boolean_t takeTypemapTypedefParam(boolean_t b) { return b; diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index e57a704d..2ced803e 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1379,6 +1379,8 @@ DLL_API char* takeConstCharRef(const char& c); DLL_API const char*& takeConstCharStarRef(const char*& c); DLL_API const void*& rValueReferenceToPointer(void*&& v); DLL_API const Foo*& takeReturnReferenceToPointer(const Foo*& foo); +DLL_API const wchar_t* takeReturnWideString(const wchar_t* wideString); +DLL_API std::wstring WideString; struct { struct {