トップページ > 記事閲覧
[task]文字列の長さ指定付き関数を追加
名前:yumetodo 日時: 2017/10/26 11:54

C++17でSTLにstd::string_viewが追加されたことにより、NULL終端しない長さがわかっている文字列を扱う機会が増えました。 しかし現在のDxLibの関数群は文字列を受け取る際、NULL終端を要求しており、 std::string_viewを渡すのに一度std::stringで動的メモリ割り付けとコピーを行う必要があり、きわめて非効率的です。 内部の実装を読んだ感じではstrlen相当の関数を読んでいるわけで(ex. DrawStringToHandleの内部実装(DrawStringHardware, DrawStringSoftwareなど)、 つまり引数で文字列へのポインタとともに長さを渡せるようにオーバーロードを追加しても実装はさして複雑にならないと考えます。 例えば DrawStringToHandle( int x, int y, const TCHAR *String, size_t StringLength, unsigned int Color, int FontHandle, unsigned int EdgeColor, int VerticalFlag ); のような関数がほしいです。
メンテ

Page: 1 | 2 |

Re: [proposal]文字列の長さ指定付き関数を追加してほしい ( No.2 )
名前:yumetodo 日時:2017/10/22 23:21

>こちら文字列を引数に取るすべて関数についてでしょうか? 文字列操作系はstring_view使う場合使わないと思うのでなくてもいいかと思われます。 >取り組むとしても現在優先している作業が終わってからになります… 了解です。
メンテ
Re: [proposal]文字列の長さ指定付き関数を追加してほしい ( No.3 )
名前:管理人 日時:2017/10/24 00:31

> 文字列操作系はstring_view使う場合使わないと思うのでなくてもいいかと思われます。 分かりました では文字列操作系以外で文字列を引数に取る関数について対応したいと思います ( 『現在優先している作業』の進捗状況が芳しくないので、取り掛かれるのは来年になってしまいそうですが… orz )
メンテ
Re: [proposal]文字列の長さ指定付き関数を追加してほしい ( No.4 )
名前:yumetodo 日時:2017/10/26 11:53

>取り掛かれるのは来年になってしまいそうですが 了解です
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.5 )
名前:yumetodo 日時:2017/12/24 13:36

書き忘れていました。string_viewはもととなる文字列を書き換えないので、それに反する関数群(といっても文字列操作系以外にはなかったはず)は対応不要です。 長さはsize_tでないといつぞやのGetColor()の戻り値問題の再発になります。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.6 )
名前:管理人 日時:2017/12/25 00:12

了解です 尚、No.3 の書き込みに引き続き『現在優先している作業』の進捗が想定より遅れているので、 最速でも取り掛かれるのは来年の2月以降になりそうです orz
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.7 )
名前:yumetodo 日時:2017/12/25 15:52

>来年の2月以降になりそうです orz お疲れ様です・・・
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.8 )
名前:管理人 日時:2018/01/31 00:35

そろそろ実装の作業ができそうなのですが、こちら書式文字列を引数に取る関数( printf( "x:%d y:%d", x, y ); のような )は 対応しなくても良いのですよね? というのも『FormatString より前に StringLength を指定しなければならなくて気持ち悪いなー』と思っていたのですが、 『そもそもこのタイプの関数も StringLength の引数を指定するバージョンがあるべきなのか?』という疑問が沸きまして・・・
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.9 )
名前:yumetodo 日時:2018/02/04 22:15

>そろそろ実装の作業ができそうなのですが おおっ! >書式文字列を引数に取る関数 いらないと思います、fmtlib/fmtにリファレンスから誘導してもらえれば幸いですが。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.10 )
名前:管理人 日時:2018/02/05 01:02

とりあえず DrawString系の関数に文字列の長さを指定するタイプの DrawNString などの関数を追加しました ( DLL にしている関係上、同名で引数の異なる関数にすることができないので別名関数になっています ) https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.exe // Windows版 C++ Builder 10.1 Berlin 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM.exe // Android版 ARM用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x86.exe // Android版 x86用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース ( 中身を既存のライブラリのファイルに上書きして、VisualStudioをお使いの場合は『リビルド』を、  BCCをお使いの場合は『再構築』をして下さい ) > いらないと思います、fmtlib/fmtにリファレンスから誘導してもらえれば幸いですが。 了解です fmtlib/fmt に関しては、分かる方だけが使う形にしたいと思うので誘導はしない方向で・・・ ところで本件の対応は LoadGraph や LoadSoundMem など、文字列を引数とする関数すべてについてご希望でしょうか?
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.11 )
名前:yumetodo 日時:2018/02/07 00:44

>とりあえず DrawString系の関数に文字列の長さを指定するタイプの DrawNString などの関数を追加しました 確認しました。 >ところで本件の対応は LoadGraph や LoadSoundMem など、文字列を引数とする関数すべてについてご希望でしょうか? 文字列の長さを受け取っても実装上内部で文字列コピーをしてNULL終端させざるを得なくなる、ということがない限りにおいて、 また文字列操作系とフォーマット文字列系を除いてすべてです。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.12 )
名前:管理人 日時:2018/02/07 01:17

ご返答ありがとうございます 了解です ですが、関数名をどうするか悩みどころですね・・・ LoadGraph_with_StringLength では長すぎる気がしますし・・・ もし yumetodoさんに何か良いアイディアがありましたらご意見ください m(_ _;m ( 多分私の場合 LoadGraph_?? のような、『_』+『何か2文字』を関数名の末尾に追加するという結論に至ると思います・・・ )
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.13 )
名前:yumetodo 日時:2018/02/07 11:04

STLがどうやっているか調べたらstd::copyに対してstd::copy_nなんてのがあるが、あれはまたちょっと違うしなぁ・・・ 下手に短くして可読性を下げるよりは、WithStrLenとかをsuffixにしたほうがいいと思います。 短くしないと実行速度が下がるどっかの言語とは違うのですし、C/C++は。 (LoadGraph_with_StringLengthって命名規則ガバガバ過ぎでは・・・)。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.14 )
名前:管理人 日時:2018/02/08 00:22

> STLがどうやっているか調べたらstd::copyに対してstd::copy_nなんてのがあるが、あれはまたちょっと違うしなぁ・・・ そうなんですよね、DrawString みたいに String とついている関数は DrawNString のようにできるのですが・・・ > 下手に短くして可読性を下げるよりは、WithStrLenとかをsuffixにしたほうがいいと思います。 ご提案ありがとうございます、では LoadGraphWithStrLen のような関数名にしてみます > (LoadGraph_with_StringLengthって命名規則ガバガバ過ぎでは・・・)。 関数名については既に( というより割と最初から )ぐちゃぐちゃなので、区別できれば良いくらいに考えています
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.15 )
名前:yumetodo 日時:2018/12/20 03:26

GetDrawStringWidthToHandleなどの関数についてはWithStrLen付きは追加されないのでしょうか? GetDrawStringWidthToHandleには第二引数で長さを指定できるため一見不要に見えますが、 実装をみると問答無用でstrlen亜種の関数(_WCSLEN)を呼び出しているため、NULL終端しない文字列を渡せません。 // 文字列の幅を得る extern int GetDrawStringWidthToHandle_WCHAR_T( const wchar_t *String, int StrLen, int FontHandle, int VerticalFlag ) { int Length ; FONTMANAGE *ManageData ; ManageData = GetFontManageDataToHandle_Inline( FontHandle ) ; if( ManageData == NULL ) { return -1 ; } Length = ( int )_WCSLEN( String ) ;//問答無用で呼び出し! if( StrLen < 0 || StrLen > Length ) { StrLen = Length ; } なおWithStrLen付きを追加する際は現状のGetDrawStringWidthToHandleでいう第二引数の型は、 intではなくsize_tにして引数の数は変更しないことで実現できると思います。 intになっているのは ttp://dxlib.o.oo7.jp/cgi/patiobbs/patio.cgi?mode=view&no=3766 >『マイナスの値を渡すと内部で文字列長を調べてくれる』というものがありまして ということだったと思うのでそれは不要だからです。 (というかこのときはこれで納得しましたが真の仕様は第二引数によらず常に文字列長を調べる、になっていませんか?) ref: ttps://qiita.com/ta_dragon/items/b30c190d2108fd915e92
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.16 )
名前:yumetodo 日時:2018/12/20 03:41

ところで話がそれますがGetDrawStringWidthToHandle_WCHAR_Tって3.17aのころは if( StrLen < 0 || StrLen > Length ) じゃなくて if( StrLen > Length ) だったから >『マイナスの値を渡すと内部で文字列長を調べてくれる』というものがありまして という機能はなかったという衝撃の事実・・・ さらにGetDrawStringCharInfoToHandle_WCHAR_Tは3.19f時点でもまだ if( StrLen > Length ) なので ・・・あれっ、あれれ?おかしいですよっ! さらに if( StrLen > Length ) でDxFont.cppを検索すると5件ヒット、ざっと見た感じ同じ問題。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.17 )
名前:管理人 日時:2018/12/22 23:50

> GetDrawStringWidthToHandleには第二引数で長さを指定できるため一見不要に見えますが、 > 実装をみると問答無用でstrlen亜種の関数(_WCSLEN)を呼び出しているため、NULL終端しない文字列を渡せません。 なるほど、確かにそうですね 近日中に追加します > if( StrLen < 0 || StrLen > Length ) >  > じゃなくて >  > if( StrLen > Length ) >  > だったから >  > >『マイナスの値を渡すと内部で文字列長を調べてくれる』というものがありまして >  > という機能はなかったという衝撃の事実・・・ 確かに仰る通りですとおかしいので手元でテストしてみましたが、メモリの不正なアクセスなどは発生しませんでした コードを確認したところ GetDrawStringCharInfoToHandle_WCHAR_T などが呼んでいる FontCacheStringDrawToHandleST の中で if( StrLen < 0 ) のチェックをしていました yumetodoさんは実際にプログラムを実行してエラーが発生することを確認された上で発言されたわけではないのでしょうか?
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.18 )
名前:yumetodo 日時:2018/12/25 02:50

>なるほど、確かにそうですね >近日中に追加します ありがとうございます。 >yumetodoさんは実際にプログラムを実行してエラーが発生することを確認された上で発言されたわけではないのでしょうか? いいえ。あくまでGetDrawStringWidthToHandle_WCHAR_Tのみ見ていて呼び出しツリーはまでたどってなかったですね・・・ ただソースコード上の対称性と保守性の観点からもうちょっとなんとかしたほうがいいかなとは思っています。
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.19 )
名前:管理人 日時:2018/12/25 23:53

GetDrawStringWidth などに DrawNString などと同じ形態の文字列長の指定を追加した GetDrawNStringWidth などの関数を追加しましたので、よろしければダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM.zip // Android版 ARM用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM64.zip // Android版 ARM64用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x86.zip // Android版 x86用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x64.zip // Android版 x64用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) > ただソースコード上の対称性と保守性の観点からもうちょっとなんとかしたほうがいいかなとは思っています。 ご指摘ありがとうございます とりあえず今回関数を追加する過程で同種の関数を一通り眺めたので、その際に if( StrLen < 0 || StrLen > Length ) の辺りの処理を統一しました
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.20 )
名前:yumetodo 日時:2018/12/26 10:57

確認しました。ありがとうございます。 なお内部実装に使っているFontCacheStringDrawToHandleSTに文字列の長さを渡す部分ですが、 FontCacheStringDrawToHandleSTの呼び出し箇所をすべて調べた限りではすべてsize_tをintにキャストしてから渡しています。 引数の型を変更するほうが良かったのではないかなどと思いました。 FontCacheStringDrawToHandleSTの内部ではDxAllocの呼び出しにしか使用していないですよね?
メンテ
Re: [task]文字列の長さ指定付き関数を追加 ( No.21 )
名前:管理人 日時:2018/12/29 06:29

> FontCacheStringDrawToHandleSTの内部ではDxAllocの呼び出しにしか使用していないですよね? いえ、FontCacheStringDrawToHandleST の内部にも StrLen がマイナスだった場合の処理が書かれています
メンテ

Page: 1 | 2 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存