August 22, 2013

Alıntı (emre413):

>

Hata: hello.d|15|Error: function hello._fileno (shared(_iobuf)* _File) is not callable using argument types (File)|

cast(FILE*)stdout denedim yine olmadı.

_fileno'nun parametresi FILE* imiş. D'nin stdout'u ise bir std.stdio.File diye bir struct. Tabii cast de olmaz çünkü bir yapı nesnesini FILE göstergesi olarak kullanmaya çalışıyoruz.

File'ın getFP üye işlevi sarmaladığı FILE göstergesini döndürür:

http://dlang.org/phobos/std_stdio.html#.File.getFP

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 23, 2013

Evet fazlaca karıştı :)

Şimdi asıl sorun yani benim düşündüğüm acaba setmode fonksiyonunu düzgün olarak çağıramıyor muyum? Çünkü C++'ta yazınca çalışıyor. Ayrıca MinGW ile de derledim yine çalıştı. Öbürünü VC++ ile denemiştim.

_setmode io.h dosyasında, _fileno stdlib.h dosyasında prototip olarak; _O_U8TEXT fcntl.h dosyasında ve stdout zaten stdio.h dosyasında tanımlı.

Ayrıca _setmode msvcrt.dll'in içinde.

Bir yerde direkt LoadLibraryA ile msvcrt.dll'den çağıran bir kod buldum D için denedim ama yine olmadı. Olmadı derken hata vermedi ama çalışmadı da. Gariplik burada.

import std.stdio;
import core.sys.windows.windows;
import std.string;

extern(C) {
   int wprintf(const wchar *format,...);
}

extern (Windows)
alias int function(int,int) setmode_f;

void main(char[][] args)
{
  const int _O_U8TEXT = 0x40000;

  setmode_f f;

  HMODULE m = cast(HMODULE) LoadLibraryA(toStringz("msvcrt.dll"));

  f = cast(setmode_f) GetProcAddress(m, toStringz("_setmode"));

  f(fileno(stdout.getFP()), _O_U8TEXT);

  f(cast(int)stdout.getFP(), _O_U8TEXT);

  wstring trKarakterler = "Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş\n"w;

  fwrite(trKarakterler.ptr, 1, trKarakterler.length, stdout.getFP());

  writef(trKarakterler);
  wprintf(trKarakterler.ptr);
}

Acaba sorun ekrana basma fonksiyonunda mı diye üç farklı fonksiyon ile denedim.

writeln(f(fileno(stdout.getFP()), _O_U8TEXT));

ile fonksiyonun dönüşüne baktım 65536 döndürdü. MSDN açıklamasında başarılı olursa bir önceki çeviri modunu döndürür diyor yanlış anlamadıysam.

65536 = 0x10000 yani _O_WTEXT

fcntl.h'da baktım.

#define _O_WTEXT        0x10000 /* file mode is UTF16 (translated) */

olarak tanımlanmış. Yani UTF16 olarak gösteriyor.

Şimdilik edindiğim bilgiler bunlar. Yine araştırmaya devam edeceğim ama bu sorun biraz zor çözülür gibi beni aşıyor :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 22, 2013

Ortalık çok karıştı. :)

Alıntı (emre413):

>
> extern(C) {
>     int wprintf(const wchar *format,...);
> }
> ```


Tamam, wprintf bir wchar* göstergesi alıyormuş.

Alıntı (emre413):
>
>
wprintf("Türkçe Karakterler: ı I İ i ö Ö ü Ü ğ Ğ ç Ç ş Ş");

O satır derleniyor mu? O dizgi hazır değerinin türü string olmalı (yani, değişmez char dizisi). Otomatik tür dönüşümü olduğunu sanmıyorum. Onun için dizginin sonunda w karakteri olmalı: "merhaba"w gibi... Sonra .ptr niteliği ile veya ilk karakterinin adresi ile wchar* elde edilir. (O da, dizgi hazır değerleri '\0' ile sonlandıkları için çalışır. Yoksa, herhangi bir dizginin sonunda '\0' yoktur.) Yani, "merhaba"w.ptr gibi deneyebilirsin.

Alıntı (emre413):

>

wprintf tanımında wchar_t yerine wchar kullandım

O bir yere kadar çalışır. Windows'un wchar_t'si UTF-16 değildir ama D'nin wchar'ı UTF-16'dır. Buna rağmen bizi ilgilendirmeyen bazı Unicode karakterleri dışında kodlar birbirlerini tutar. (Windows Unicode'u çok geç anlayabilmiştir.)n

Alıntı:

>

karakterler doğru basılmadı

Elimde Windows sistemi olmadığı için yardım da edemiyorum.

Ama biraz duralım ve yavaş yavaş sırayla gidelim. C++ programını da bir kenara bırakalım lütfen. D programını anlamada kafamızı karıştırmaktan başka hiçbir işe yaramıyor. (Hatta, C++ kaynak kodunun UTF-8 olabilmesi ise sanırım ancak C++11 ile mümkün oldu.)

  1. D'de char dizgileri UTF-8'dir. Bundan kaçış yok. Dolayısıyla, "ü" dizgisi iki adet UTF-8 baytından oluşur.

  2. O baytlar çıkışa yazdırıldıklarında doğal olarak iki adet UTF-8 kodu olarak yazdırılırlar.

  3. Çıkışta konsol var. Konsol eline teker teker iki bayt geçirir. O baytları ne yapsındır? Eğer 1254'e veya başka bir karakter tablosuna ayarlanmışsa her birisini tek karakter olarak algılar ve iki adet karakter yazdırır. ü'nün UTF-8'deki iki baytının değeri 1254'te hangi karakterlere karşılık geldiyse konsol onları gösterir.

Dolayısıyla, konsolu UTF-8'e ayarlamazsak D programının doğru göstermesi mümkün değildir. (Aslında dizgiyi yazdırmadan önce kendimiz bir tercüme de yapabiliriz: Örneğin, ü yerine 1254'teki karşılığını yazdırabiliriz ama her write'tan önce buna dikkat etmek gerekeceğinden onu bir kenara bırakalım.)

  1. Konsol UTF-8 olsa bile kullanılan fontun da Unicode karakterlerini içermesi gerekir. Bunun iki yolu olmalı:

Birincisini denedik ve başaramadık: Fontu program içinden seçmek.

İkinci yöntem, konsol için seçilen fontu sistem düzeyinde değiştirmek. Bir anlamda, varsayılan fontu bir kere seçmek. Bu, programın herhangi bir Windows ortamında işlediği durumu kurtarmıyor ama bizim için bir çözüm olabilir.

Benim anladığım bu. Tabii bunun tersi de gerekiyor:

  1. Klavyenin fiziksel olarak sağ taraflarındaki o tuşun ü olduğu seçilmiş olan klavye düzeninden bilinmektedir.

  2. Konsol ü'ye basıldığını öylece anladığı için onun karşılığı olan iki UTF-8 baytını programın girişine verir.

  3. D programı da UTF-8 olduğundan iki baytı olduğu gibi alır ve char dizisinin içine yerleştirir.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

1 2 3 4
Next ›   Last »