Från och till NSString resp. wchar_t

Tråden skapades och har fått 7 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Stockholm
  • 2008-02-16 18:26

Hej!

Sitter och försöker koppla ihop en komponent i c++ med Cocoa, och det funkar utmärkt utom när det gäller att konvertera strängar från och till NSString/wchar_t. Hur är det tänkt att man ska gå till väga? Körde först med cStringUsingEncoding, och det verkade fungerade alldeles utmärkt ända tills jag begrep att den sträng som spottas ut inte är nollterminerad, och det verkar ju inte finnas någon direkt enkelt sätt att kolla hur lång strängen är innan man har konverterat den. (Hur har dom tänkt när de returnerar en c-sträng som inte är nollterminerad?)

Efterom jag är totalt rudis när det gäller Mac-utveckling i allmänhet och Cocoa i synnerhet anar jag att det finns ett enkelt och elegant sätt att göra den här konverteringen på.

  • Medlem
  • Stockholm
  • 2008-02-17 11:24

Jo, jag var där och rotade innan jag postade här, men jag blev inte mycket klokare för det. I dagsläget får jag ut en unichar-sträng med getCharacters som jag sedan konverterar "för hand" till wchar_t. Det fungerar rent tekniskt men känns onödigt och oestetiskt. Hoppades att det fanns ett vettigare sätt.

  • Medlem
  • Knivsta
  • 2008-02-17 12:08
Ursprungligen av marfuas:

Körde först med cStringUsingEncoding, och det verkade fungerade alldeles utmärkt ända tills jag begrep att den sträng som spottas ut inte är nollterminerad, och det verkar ju inte finnas någon direkt enkelt sätt att kolla hur lång strängen är innan man har konverterat den. (Hur har dom tänkt när de returnerar en c-sträng som inte är nollterminerad?)

Är den verkligen inte nollterminerad? Manualen (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/doc/uid/20000154-BAJHJHHD) påpekar att datat som returneras från dataUsingEncoding:allowLossyConversion: inte är det, men det säger ju inget om cStringUsingEncoding:. Fast jag har inte testat...

  • Medlem
  • Stockholm
  • 2008-02-17 12:28

Visst är det mysko? Om man kollar här http://trac.aarone.org/cicu/browser/trunk/source/NSStringICUAdditions.m?rev=17 (rad 81) verkar andra ockå ha haft liknande problem. Minns inte riktigt hur jag kom fram till att det var NSString som betedde sig konstigt, och inte jag. Kan försöka verifiera det ordentligt i morgon på jobbet.

  • Medlem
  • Stockholm
  • 2008-02-18 13:18

Ja, såvitt jag kan bedöma så är det verkligen så. Följande snutt ger lite då och då någonting annat i slutet av strängen än en nolla:

const wchar_t* probe;
	NSString* test;
	
	test = [textField stringValue];
	probe = (const wchar_t*)[test cStringUsingEncoding:NSUTF32StringEncoding];
	NSAssert(probe, @Null);
	if(probe[[test length] + 1] != 0){
			NSLog(@Not zero);
	}	

textField är en NSTextField i en simpel dialogruta. Man måste köra snutten först med en lång sträng och sedan en kortare i textrutan för att provocera fram felet.

Får samma beteende för NSUTF8StringEncoding och NSASCIIStringEncoding.

Som alltid är det mycket möjligt att jag har sluntit på tangenterna och/eller inte läst manualen ordentligt. Hojta gärna i så fall!

Men originalfrågan kvarstår: Vad tycker Apple att man ska använda?

  • Medlem
  • Knivsta
  • 2008-02-19 18:31

Nu är jag trött efter en dag på jobbet så jag kanske är ute och cyklar, men: borde du inte titta på probe[[test length]] i stället för på probe[[test length] + 1]? Det förklarar dock naturligtvis inte varför koden du länkade till råkat ut för samma problem. Den har å andra sidan problemet att den gör antaganden om längden på en UTF-16-sträng vilket verkar riskabelt. Å tredje sidan borde inte surrogatpar dyka upp speciellt ofta...

Finns det någon teckensekvens det alltid blir fel på, eller verkar det slumpmässigt?

Vild idé: Kan det vara så att den genererade strängen termineras med en noll-_byte_, oavsett hur breda tecken den innehåller? Det vore ju en småkul bug i så fall.

  • Medlem
  • Stockholm
  • 2008-02-20 11:13

Ska förstås vara probe[[test length]], men problemet uppstår ändå. Jag kan inte hitta något direkt mönster, det kan funka för tre-fyra strängar i rad och plötsligt paja för nästa sträng (särskilt om den är kortare). Får samma beteende även för "aaaaaa" följt av "a".

Kuriöst nog kan jag inte reproducera problemet om jag kompilerar programmet i Release-läge. Det kan inte vara så att jag har gjort nåt fel med allokeringar på ett helt annat ställe (glömt ett retain eller vad vet jag) som pajar en intern buffert nånstans inne i implementationen av NSString?

Jag skulle kunna tänka mig att strängen alltid termineras med en nollbyte, särskilt som man får en const char* tillbaka. Men för att kontrollera det skulle man behöva peta in ett UTF32-tecken som inte är noll i första byten (finns det ens såna?).

1
Bevaka tråden