ホーム » gcc
「gcc」カテゴリーアーカイブ
argv envp
以前 Linux 環境で動作する .out で,コマンドラインを取得したくなり作成したコード.
Windows でもそのまま動作する様に作成したもので,予め main でグローバルな変数に argv を登録している.
#include "cmd_line.hxx"
int _tmain (int argc,TCHAR* argv[],TCHAR* envp[])
{
{
::reg_argv(argc,argv,envp) ;
}
{
::dmp_arg() ;
}
return 0 ;
}
Windows の場合は __argc と __argv が利用できるのであまり必要ない.
::GetCommandLine を使用することも可能.
コンパイル時の #define 値の表示
次の様なコードをコンパイル時に表示したくなった.
#ifdef _MSC_VER
str = _T("_MSC_VER ") + ::utot(_MSC_VER,10) ;
#endif
std::tout << str ;
以前一度使用しているが,それをもう少しいろいろと...
次の様に _CRT_STRINGIZE とすれば _MSC_VER 1941 と表示される.
#ifdef _MSC_VER
#pragma message ("_MSC_VER " _CRT_STRINGIZE(_MSC_VER) )
#endif
VC 14 以降は vcruntime.h で次の様になっている.
#define _CRT_STRINGIZE_(x) #x
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)
フォルダの更新日時の設定
以前に作成した mtime を更新するツール.
データファイルなどの更新日時を揃えるために作成したもの.
更新日時の設定は CFile::SetStatus で行っている.
CString file = UpdateFiles[index] ;
CFileStatus fs ;
CFile::GetStatus(file,fs) ;
fs.m_mtime = newTime ;
CFile::SetStatus(file,fs) ;
このツールではフォルダの更新日時は変更できない.
その後 Linux 環境などでも動作する様なコードを作成.
utime を使用したもの.
Linux 環境ではフォルダに対してもうまく動作するが,Windows 環境では相変わらず.
ここまでは,以前調べたもの.
2ヶ月ほど前だったと思うが,検索していて次のページを見つけた.
ファイル・フォルダーの更新日時を変更
改めて CFile::SetStatus や _utime の中身を見ると,動作は同じで ::CreateFile と ::SetFileTime を呼出している.
デバッガで追いかけていると ::CreateFile で失敗している.errno は 13 .
::CreateFile を次の様に指定して呼出すと,ファイルの場合は問題ないがフォルダは NG .
HANDLE hFile = ::CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL) ;
フォルダの場合 FILE_FLAG_BACKUP_SEMANTICS が指定されていなければならないみたい.
HANDLE hFile = ::CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL) ;
time_t から FILETIME への変換は次の所.
https://learn.microsoft.com/ja-jp/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time
SetFTime.hxx
2024/08/09
https://itl.mish.work/i_Tools/Doc/blog/vc/UpdateMT.zip
角の二等分線
https://en.wikipedia.org/wiki/Bisection
wiki にあるアニメーションをコードにしたもの.
Ld2 V2_get_bisector (const Vd2& vp,const Vd2& vc,const Vd2& vn)
{
// * vp
// |
// |
// | * vcx
// | /
// | o /
// | / o
// vc * - - - - - - * vn
Vd2 vcp = (vp-vc).Normalized() ;
Vd2 vcn = (vn-vc).Normalized() ;
Vd2 vcb = (vcp+vcn)/2. ;
Vd2 vcx = vcb + vc ;
{
vcx = ::get_cross_line(vp,vn,vc,vcx) ;
}
Ld2 lbs(vc,vcx) ;
return lbs ;
}
青い円弧が,最初の 2 行の Normalized .
次の中点を求めているのは,赤い円弧の交点を結ぶ線にあたる.
二等分線を対辺?まで延長.
Linux での GLUT 3D データ表示
昨日のコードをもう少し汎用的に修正.そしてそれを他から呼出せるように変更.
次の様なコードで 3D データを生成して,GLUT で表示できる様にした.
bool test (void)
{
Vd2A pts ;
{
pts.push_back(Vd2( 0, 0)) ;
pts.push_back(Vd2( 70, 0)) ;
pts.push_back(Vd2( 90, 50)) ;
pts.push_back(Vd2(100,100)) ;
pts.push_back(Vd2( 50,100)) ;
pts.push_back(Vd2( 30, 70)) ;
pts.push_back(Vd2( 40, 30)) ;
pts.push_back(Vd2( 0, 0)) ;
}
vv_PLF vvplf ;
{
Vd3A v3a = ::ToVd3A(pts) ;
Vd4A v4a = ::ToVd4A(v3a) ;
PLF plf_l__ (PLF::line,v4a) ;
PLF plf_f__ (PLF::face,v4a) ;
v_PLF v_plf ;
v_plf.push_back(plf_l__) ;
v_plf.push_back(plf_f__) ;
vvplf.push_back(v_plf) ;
}
tstring txt_name = ::g3_d_get_txt_name() ;
{
tstring tmp_path = ::Get_i_Tools_tmp_date() ;
tstring ipl_name = ::Path_AddLastSP(tmp_path) + ::Now_Format(_T("%H%M%S")) + _T(".ipl") ;
::To_ipl (vvplf,ipl_name.c_str()) ;
::SaveText(txt_name.c_str(),ipl_name) ;
}
{
::exec_g3_d(txt_name.c_str()) ;
}
return true ;
}
C++ メンバ関数テンプレート
.ini に対してのアクセスは関数として用意した が,今度はレジストリ.
クラスとして実装して,基本的な動作は何とかできた.
さらに .ini と同様に,文字列としてアクセスする部分を呼出す関数をテンプレートに…
と思って書き始めたが,今まで使ってなかったのか書き方がわからない.
検索すると,次の所があり参考にさせてもらった.
メンバ関数テンプレート | Programming Place Plus C++編【言語解説】 第33章
メンバー関数テンプレート
特に通常の関数テンプレートと書き方は変わらない.
template <typename T> T get ( LPCTSTR ent,const T& def) {
tstring dst = ::To_tstring(def) ;
tstring str = this->get(ent,dst.c_str()) ;
T val ;
::string_to(str.c_str(),&val) ;
return val ;
}
template <typename T> bool set ( LPCTSTR ent,const T& val) {
tstring str = ::To_tstring(val) ;
return this->set(ent,str.c_str()) ;
}
C++ 戻り値の異なる関数 template
先日からやっている .ini やレジストリにアクセスする関数.
MFC の CWinApp::GetProfileString , CWinApp::WriteProfileString にあたる部分は目途がついた.
それで,それらを呼出す部分.前に作成したものもそうだったが,型ごとにクラスの関数を定義していた.
これらをもう少し簡単にできないかと…
set の方は,特に難しい所はない(::To_tstring は,文字列に変換する関数として用意している).
template <class T> bool INI_set (LPCTSTR sec,LPCTSTR ent,const T& val)
{
tstring ini = ::INI_get_module_ini() ;
tstring str = ::To_tstring(val) ;
return ::INI_set(ini.c_str(),sec,ent,str.c_str()) ;
}
get の場合,文字列から変数に変換する方法をどうするか?
例えば,atoi や atof ,他にも 4 つの整数の文字列を RECT に変換するなど.
検索すると template で可能みたい だが…
よくわからなかったので,簡単な方法にした.
inline RECT To_RECT (LPCTSTR str)
{
RECT rect = { 0 } ;
{
v_tstring str_ary = ::String_SplitSpace(str,_T(" ,\t\r\n")) ;
if (0 < str_ary.size()) { rect.left = ::ttoi4(str_ary[0]) ; }
if (1 < str_ary.size()) { rect.top = ::ttoi4(str_ary[1]) ; }
if (2 < str_ary.size()) { rect.right = ::ttoi4(str_ary[2]) ; }
if (3 < str_ary.size()) { rect.bottom = ::ttoi4(str_ary[3]) ; }
}
return rect ;
}
inline bool string_to (LPCTSTR str,RECT* rect_) { *rect_ = ::To_RECT (str) ; return true ; }
inline bool string_to (LPCTSTR str,POINT* point) { *point = ::To_POINT(str) ; return true ; }
inline bool string_to (LPCTSTR str,SIZE* size_) { *size_ = ::To_SIZE (str) ; return true ; }
それぞれの型に合わせた関数を呼べるようになったので template に.
template <class T> T INI_get (LPCTSTR sec,LPCTSTR ent,const T& def)
{
tstring ini = ::INI_get_module_ini() ;
tstring dst = ::To_tstring(def) ;
tstring str = ::INI_get(ini.c_str(),sec,ent,dst.c_str()) ;
T val ;
::string_to(str.c_str(),&val) ;
return val ;
}
これで,次の様な使い方ができる様になる.
{
POINT point = ::POINT_set( 10, 20) ;
SIZE size_ = :: SIZE_set( 1111, 525) ;
RECT rect_ = :: RECT_set(point,size_) ;
{
::INI_set(_T("test"),_T("rect_"),rect_) ;
::INI_set(_T("test"),_T("point"),point) ;
::INI_set(_T("test"),_T("size_"),size_) ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("rect_"),rect_)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("point"),point)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("size_"),size_)) << std::endl ;
}
}
C++ NonCopyable
MFC を使用しないコードに書き直していて,代入できない構造体が欲しくなった.
オリジナルのコードは 20 年以上前のもので,CRegKey が簡単には使えなかった?頃.
「C++ クラス 代入できなくする」で検索.
コピー禁止を徹底させるNoncopyableクラス
More C++ Idioms/コピー禁止ミックスイン(Non-copyable Mixin)
明示的に既定された関数および削除された関数
MFC の CObject も同様と思いソースを見ると,やはり private になっている.
C++11 以降では =delete も使える.
関数のdefault/delete宣言
wiki C++11
これらを調べていて,次の所を見つけた.
旧時代のC言語を使うのはそろそろやめよう。
2016年、C言語はどう書くべきか (前編)
2016年、C言語はどう書くべきか (後編)
幾つかは既に意識しているが,Windows に依存する部分はなかなかできてない.
buf = string ( buf.c_str () )
先日の共通のコードでのバグ.
tstring ask_cli (LPCTSTR msg=_T(""))
{
tstring cli ;
while(true) {
tstring buf ;
buf.resize(1000) ;
std::terr << msg ;
std::tin.getline(&buf[0],std::streamsize(buf.size())) ;
// buf = ::QuotM_Del_All(buf.c_str()) ;
if (buf == _T("q")) { break ; }
else if (buf == _T("Q")) { break ; }
if (buf.empty()) { continue ; }
cli = buf.c_str() ;
break ;
}
return cli ;
}
ループを抜けるために “q” や “Q” と比較している部分が機能しない(break しない).
原因は “q\0\0\0…” と “q\0” を比べているため.
そのため,比較する前に次の様にするとうまく機能する.
{
tstring tmp = buf.c_str() ;
buf = tmp ;
}
MFC であれば CString::ReleaseBuffer(-1) が使えるが…
buf = tstring(buf.c_str()) とすることで対応.
コンソール AP のための最初のコード
API などをテストするために,個人的に使用している C++ のコード.
#include <clocale>
#include <iostream>
#include "_tdefine.hxx"
#include "cmd_line.hxx"
#include "ask_cli.hxx"
//#include "ask_path.hxx"
bool test (c_tstring& str)
{
std::terr << str << std::endl ;
return true ;
}
inline bool call_func (int argc,TCHAR* argv[])
{
if (argc > 1) {
for (int index=1 ; index<argc ; index++) {
tstring av = argv[index] ;
::test(av) ;
}
}
else {
while(true) {
tstring path ;
{
#ifdef OFN_filter_All
path = ::ask_path(false) ;
#else
path = ::ask_cli(_T("file ... ? =")) ;
#endif
}
if (path.empty()) { break ; }
::test(path) ;
}
}
return true ;
}
int _tmain (int argc,TCHAR* argv[])
{
_tsetlocale(LC_ALL,_T("")) ;
{
::reg_argv (argc,argv) ;
}
{
::call_func(argc,argv) ;
}
{
::test(_T("Test")) ;
}
::ask_wait() ;
return 0 ;
}
//#include "messbar.cxx"
インクルードしているファイルは cpp6_hxx.zip にある.
上のコードを test.cpp などとして保存し,同じ所に zip を展開.
g++ test.cpp などでコンパイル可能.
これらを使用したコード.
https://dev.mish.work/wordpress/?s=reg_argv
vector<long> などを文字列に
std::vector<long> の文字列への変換.
何年も前に書いたコードで,使い方を忘れているのでそのまとめ.
次の様な関数を用意している.
template <class VX> tstring Vx_To_tstring(const VX& vx,LPCTSTR sp=_T(" "))
次の様な使い方で long の配列を文字列へ変換できる.
tstring vl_str = ::Vx_To_tstring<v_long>(long_ary) ;
DS116 entware
localtime が正しく求められない ままの環境.
https://jml.mish.work/index.php/various/nas/synology-nas.html
ある程度 DS220+ に移行したので,SSH 接続環境の再設定.
CLI コマンドの導入.
DS220+ と同様 .
名前 :「SynoCommunity」
場所 :「https://packages.synocommunity.com/」
「SynoCli File Tools」をインストールして tree , mc , nano などを追加.
これで追加した tree は,localtime が正しく求められている.
Entware のインストール.
Install on Synology NAS
Iwao@DS116:~$ sudo -i
Password:
root@DS116:~# mkdir -p /volume1/@Entware/opt
root@DS116:~# rm -rf /opt
root@DS116:~# mkdir /opt
root@DS116:~# mount -o bind "/volume1/@Entware/opt" /opt
root@DS116:~# uname -m
armv7l
root@DS116:~# wget -O - https://bin.entware.net/armv7sf-k3.2/installer/generic.sh | /bin/sh
--2022-06-15 14:51:04-- https://bin.entware.net/armv7sf-k3.2/installer/generic.sh
タスクスケジューラの登録.
「作成」-「トリガーされたタスク」-「ユーザー指定のスクリプト」.
「Entware」「root」「ブートアップ」を指定.
「タスク設定」タブのスクリプトを記述するの所に,貼り付け.
NAS を再起動.
gcc のインストール.
Iwao@DS116:~$ sudo -i
root@DS116:~# opkg update
Downloading http://bin.entware.net/armv7sf-k3.2/Packages.gz
Updated list of available packages in /opt/var/opkg-lists/entware
root@DS116:~# opkg install gcc
Installing gcc (7.4.0-7) to root...
DS220+ セットアップ-4
前回の設定で PHP などが動作する様になったので,今度は opkg のインストール.
その前に,インストールしていない状態で,何か動作するかをチェック.
以前書いた,次のコード.
#include "pref_ini.hxx"
#include <iostream>
#include "get_path.hxx"
#include "i_Trace.hxx"
int _tmain (int argc,TCHAR* argv[])
{
_tsetlocale(LC_ALL,_T("")) ;
{
std::tout <<::TGetEnv(_T("TEMP")) << std::endl ;
std::tout <<::TGetEnv(_T("USERNAME")) << std::endl ;
std::tout <<::TGetEnv(_T("USER")) << std::endl ;
std::tout <<::TGetEnv(_T("HOMEPATH")) << std::endl ;
}
{
tstring iniPath = ::Path_AddLastSP(::GetCWD()) + _T("Test.ini") ;
tstring result = ::P_ini_Get(iniPath.c_str(),_T("Preference"),_T("server"),_T("")) ;
std::tout << result << std::endl ;
}
return 0 ;
}
以前コンパイルした a.out は動作した.
この頃はまだ他社 NAS の購入前なので,DS116 と,仮想マシンの Linux 環境で作成したものと思う.
他のものを幾つか試したが,ほとんど動作しない.
Iwao@DS220:~/gcc_test/Test/t_linux/t_mtime/t_m_time$ ./f.out
./f.out: /lib64/libc.so.6: version `GLIBC_2.33' not found (required by ./f.out)
./f.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./f.out)
Iwao@DS220:~/gcc_test/Test/t_linux/t_mtime/t_m_time$
以前 opkg のインストールは面倒だった と記憶している.
それで,新しい情報がないかと検索すると QNAP NAS と似た様なものがあった.
Packages for Synology NAS
が,この中に Entware はなさそう?
更に検索すると,
Synology NAS DS213JへAria2をインストール
Community Package Hub
こちらの方かと思いやってみたが,エラーとなる.
結局以前と同じ方法で.
Install on Synology NAS
Iwao@DS220:~$ Iwao@DS220:~$ sudo -i
root@DS220:~# ll /opt
ls: cannot access '/opt': No such file or directory
root@DS220:~# mkdir -p /volume1/@Entware/opt
root@DS220:~# mkdir /opt
root@DS220:~# mount -o bind /volume1/@Entware/opt/ /opt
root@DS220:~# wget -O - https://bin.entware.net/x64-k3.2/installer/generic.sh | /bin/sh
Will not apply HSTS. The HSTS database must be a regular and non-world-writable file.
NAS を再起動.
gcc のインストール.
Iwao@DS220:~$ Iwao@DS220:~$ sudo -i
root@DS220:~# opkg update
Downloading http://bin.entware.net/x64-k3.2/Packages.gz
Updated list of available packages in /opt/var/opkg-lists/entware
root@DS220:~# opkg install gcc
Installing gcc (7.4.0-7) to root...
root@DS220:~#
::GetDiskFreeSpaceEx , ::statvfs
Win9x が多く存在していた頃のコードの MFC を使用しない方法での書き直し.
前のものは次の様になっている.
// J048221 SDK32:GetDiskFreeSpace と GetDiskFreeSpaceEx について
typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR, PULARGE_INTEGER,PULARGE_INTEGER, PULARGE_INTEGER);
// ..
fResult = ::GetDiskFreeSpace(pszDrive,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters) ;
if (fResult) {
TotalBytes = (__int64)TotalClusters * SectorsPerCluster * BytesPerSector ;
TotalFreeBytes = (__int64)FreeClusters * SectorsPerCluster * BytesPerSector ;
FreeBytesAvailable = TotalFreeBytes ;
}
// ..
{
P_GDFSE pGetDiskFreeSpaceEx = NULL;
#ifdef UNICODE
pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),"GetDiskFreeSpaceExW") ;
#else
pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),"GetDiskFreeSpaceExA") ;
#endif
if (pGetDiskFreeSpaceEx) {
fResult = pGetDiskFreeSpaceEx (pszDrive,
(PULARGE_INTEGER)&FreeBytesAvailable,
(PULARGE_INTEGER)&TotalBytes,
(PULARGE_INTEGER)&TotalFreeBytes);
}
}
https://www.betaarchive.com/wiki/index.php?title=Microsoft_KB_Archive/231497
Windows 環境では次の様な感じ?
class DiskFree {
public:
DiskFree () { Free = Total = 0 ; }
public:
u_64 Free ;
u_64 Total ;
} ;
DiskFree GetDiskFree (LPCTSTR path)
{
DiskFree df ;
u_64 freeC = 0 ;
u_64 free = 0 ;
u_64 total = 0 ;
if (::GetDiskFreeSpaceEx(path,(PULARGE_INTEGER)&freeC,(PULARGE_INTEGER)&total,(PULARGE_INTEGER)&free)) {
df.Free = free ;
df.Total= total;
}
return df ;
}
Linux 環境では ::statvfs が使えるみたいで,次の様なコードで取得してデバッガで確認.
#include <iostream>
#include <sys/statvfs.h>
int main()
{
struct statvfs vfs = { 0 } ;
::statvfs(".", &vfs) ;
return 0 ;
}
vfs {...} statvfs
f_bsize 4096 unsigned long
f_frsize 4096 unsigned long
f_blocks 1452408524 __fsblkcnt_t
f_bfree 200259802 __fsblkcnt_t
f_bavail 199469255 __fsblkcnt_t
f_files 183001088 __fsfilcnt_t
f_ffree 181248356 __fsfilcnt_t
f_favail 181248356 __fsfilcnt_t
f_fsid 3941329918106335254 unsigned long
f_flag 4096 unsigned long
f_namemax 255 unsigned long
__f_spare int [6]
[0] 0 int
[1] 0 int
[2] 0 int
[3] 0 int
[4] 0 int
[5] 0 int
Iwao@AS5202T:/volume1/home/Iwao $ cd gcc_test/Test/t_linux/T_vfs/T_s_vfs/
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/T_vfs/T_s_vfs $ ll
total 12
drwxrwxrwx 2 Iwao users 4.0K Jul 1 22:01 ./
drwxrwxrwx 4 Iwao users 4.0K Jul 1 22:00 ../
-rwxrwxrwx 1 Iwao users 581 Jul 1 21:55 T_s_vfs.cpp*
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/T_vfs/T_s_vfs $ cat T_s_vfs.cpp
#include <iostream>
#include <clocale>
#include <sys/statvfs.h>
#include "_tdefine.hxx"
#include "t_tstrng.hxx"
int _tmain (int argc,TCHAR* argv[])
{
_tsetlocale(LC_ALL,_T("")) ;
{
struct statvfs vfs = { 0 } ;
if (::statvfs(".", &vfs) == 0) {
u_64 free = vfs.f_bavail * vfs.f_frsize ;
u_64 total= vfs.f_blocks * vfs.f_frsize ;
std::tout << ::To_tstring_Ki(free) << _T(" / ") << ::To_tstring_Ki(total) << std::endl ;
std::tout << ::To_tstring_cs(free) << _T(" / ") << ::To_tstring_cs(total) << std::endl ;
}
}
return 0 ;
}
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/T_vfs/T_s_vfs $ g++ T_s_vfs.cpp -Wall
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/T_vfs/T_s_vfs $ ./a.out
760.90 G / 5.41 T
817,005,420,544 / 5,949,065,314,304
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/T_vfs/T_s_vfs $
なんかおかしい? DS116 localtime
2020/12/02 0 時過ぎ,個人的に書いているコードがうまく動作していないことに気づいた.
全てではないが,日時の表示が GMT になってしまっている?
うまく動作しているものもあり,次のものは正しく表示される.
この様になった心当たりはある.
昨日 opkg の update と upgrade ,opkg install gcc などを行ったことが影響している?
tree … -D や cal なども GMT になっている.
どこが影響しているかを調べるために少しコードを書いてみた.
#include <clocale> #include <iostream> #include "_tdefine.hxx" #include "timefmt.hxx" int _tmain (int argc,TCHAR* argv[]) { _tsetlocale(LC_ALL,_T("")) ; { tstring now_time = ::Now_Format() ; std::tout << _T("::Now_Format() \t") << now_time << std::endl ; } { tstring gmt_time = ::Now_FormatGMT() ; std::tout << _T("::Now_FormatGMT()\t") << gmt_time << std::endl ; } return 0 ; }
Win10 環境では意図した動作.
Microsoft Windows [Version 10.0.18363.1198] (c) 2019 Microsoft Corporation. All rights reserved. C:\Users\Iwao>\\TestXP\C_Temp\Test_cpp\t_mtime\t_localt\Release.060\t_localt.exe ::Now_Format() 2020/12/02 10:22:34 ::Now_FormatGMT() 2020/12/02 01:22:34 C:\Users\Iwao>
DS116 では localtime が正しく求まっていない.
Iwao@DS116:~/gcc_test/Test/t_linux/t_mtime/t_localt$ ll total 44 drwxrwxrwx+ 2 Iwao users 4096 Dec 2 10:19 . drwxrwxrwx+ 5 Iwao users 4096 Dec 2 10:03 .. -rwxrwxrwx 1 Iwao users 14188 Dec 2 10:19 a.out -rwxrwxrwx+ 1 Iwao users 892 Dec 2 10:02 t_localt.BAK -rwxrwxrwx+ 1 Iwao users 917 Dec 2 10:17 t_localt.cpp -rwxrwxrwx+ 1 Iwao users 4476 Dec 2 10:02 t_localt.dsp Iwao@DS116:~/gcc_test/Test/t_linux/t_mtime/t_localt$ ./a.out ::Now_Format() 2020/12/02 01:24:30 ::Now_FormatGMT() 2020/12/02 01:24:30 Iwao@DS116:~/gcc_test/Test/t_linux/t_mtime/t_localt$
上の WebGL で現在日時を表示ている .out は,2017/07/19 にコンパイルしたもの.
他の .out で,古いものは正しく動作し,2020/02 のものはうまくない.
どこかに設定などがあるのか?
2020/12/09
GMT と同じ扱いになり困っていたのは,個人的なコードの i_drawlg.hxx .
今日のファイルを求める所で 24*60*60 を加えることで対応.
2022/06/15 DS116 entware
entware の更新で正しく動作する様になった.
NAS 上で OpenMP ?
今まで Windows 上で動かしていた OpenMP 対応のコードを,NAS 上で…
QNAP NAS 上にソースをコピーしてコンパイルすると
[Iwao@TS253D T_cmb_f]$ g++ T_cmb_f.cpp -Wall -fopenmp In file included from T_cmb_f.cpp:12:0: /share/Public/CloudD/GoogleD/Develop/_.SRC/Test/t_g3d_et.hpp:12:10: fatal error: omp.h: No such file or directory #include <omp.h> ^~~~~~~ compilation terminated. [Iwao@TS253D T_cmb_f]$
もう少し単純なコードで…
#ifdef _OPENMP #include <omp.h> #endif #include <clocale> #include <iostream> #include "i_define.hxx" bool Test (void) { #ifdef _OPENMP #pragma omp parallel for #endif for (long index=0 ; index<20 ; index++) { #ifdef _OPENMP #pragma omp critical (wait) #endif std::cout << index << std::endl ; } return true ; } int _tmain (int argc,TCHAR* argv[]) { _tsetlocale(LC_ALL,_T("")) ; { ::Test() ; } return 0 ; }
[Iwao@TS253D T_cmb_f]$ cd ../T_omp/ [Iwao@TS253D T_omp]$ g++ T_omp.cpp -Wall -fopenmp T_omp.cpp:10:10: fatal error: omp.h: No such file or directory #include <omp.h> ^~~~~~~ compilation terminated. [Iwao@TS253D T_omp]$
これとは直接関係ないが,
普通にコンパイルした T_cmb_f を QNAP NAS で実行すると,CPU などの温度が正しく表示されない状態に陥った.
2021/05/24
Ubuntu Linux Station ではうまく動作する.
Linux Center でも動作する.
フォルダの更新日時の変更
今までファイルの更新日時の変更は使っていた.
https://www.vector.co.jp/soft/winnt/util/se500182.html
が,このツールでフォルダの更新日時を変更しようとするとできない.
コードは CFile::SetStatus を使用している.
CFileStatus fs ; CFile::GetStatus(file,fs) ; fs.m_mtime = newTime ; CFile::SetStatus(file,fs) ;
CFile::SetStatus の中(…\atlmfc\src\mfc\filest.cpp)を見ると ::SetFileTime を使用している.
また Linux などでも使える utime(…\crt\src\utime.c)も ::SetFileTime を使っている.
VC 6 で作成したものをデバッガで追いかけると ::CreateFile で 0xffffffff が返ってきている.
ASUSTOR NAS で試すと,特に問題なく変更できる.
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/t_mtime/t_utime $ cat t_utime.cpp #include <clocale> #include "i_trace.hxx" #include "filetime.hxx" #include "itls_tmp.hxx" #include "c_which.hxx" int _tmain (int argc,TCHAR* argv[]) { _tsetlocale(LC_ALL,_T("")) ; { tstring temp_path = ::Get_i_Tools_tmp_date() ; tstring fold_path = ::Path_AddLastSP(temp_path) + ::Now_Format(_T("%H%M%S")) ; tstring file_path = ::Path_AddLastSP(temp_path) + ::Now_Format(_T("%H%M%S")) + _T(".tmp") ; { ::Folder_Create (fold_path) ; ::File_CreateEmpty(file_path) ; } { time_t f_time = ::File_GetMTime(file_path.c_str()) ; f_time-= 3600*24*7 ; ::File_SetMTime(file_path.c_str(),f_time) ; ::File_SetMTime(fold_path.c_str(),f_time) ; } { tstring cmd = tstring(cmd_ls_la) + _T(" ") + ::QuotM_Add_Auto(temp_path) ; _tsystem(cmd.c_str()) ; } } return 0 ; } Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/t_mtime/t_utime $ g++ t_utime.cpp -Wall Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/t_mtime/t_utime $ ll total 136 drwxrwxrwx 2 Iwao users 4.0K Nov 7 16:24 ./ drwxrwxrwx 3 Iwao users 4.0K Nov 7 15:32 ../ -rwxr-xr-x 1 Iwao users 122.7K Nov 7 16:24 a.out* -rwxrwxrwx 1 Iwao users 838 Nov 7 16:22 t_utime.cpp* Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/t_mtime/t_utime $ ./a.out total 0 drwxr-xr-x 3 Iwao users 80 Nov 7 16:24 . drwxr-xr-x 3 Iwao users 60 Nov 7 16:24 .. drwxr-xr-x 2 Iwao users 40 Oct 31 16:24 162451 -rw------- 1 Iwao users 0 Oct 31 16:24 162451.tmp Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/t_linux/t_mtime/t_utime $
2024/01/04
フォルダの更新日時の設定
構造体の初期化
幾つかの Windows API を呼び出す所を書き換えていて,
RECT や POINT の構造体の初期化で色々と気になり少し調べたことのまとめ.
class として書く場合は,コンストラクタで初期化しているので意識しない.
struct Vector2 { // Vector2 () {} Vector2 (T v=0) : x(v), y(v) {} Vector2 (T x, T y) : x(x), y(y) {} // ... T x ; T y ; } ;
MFC を使用している時も同様.
CRect rect(0,0,0,0) ;
他の Win32 の構造体だと
MEMORYSTATUSEX memStat ; memset(&memStat,0,sizeof(MEMORYSTATUSEX)) ; memStat.dwLength= sizeof(MEMORYSTATUSEX) ; ::GlobalMemoryStatusEx(&memStat) ;
Windows では ::ZeroMemory を使っていることもあり.
#define ZeroMemory(pb,cb) memset((pb),0,(cb))
これまで RECT を 0 にする場合,次の様にも書いていた.
RECT rect = { 0,0,0,0 } ;
次の様に省略する方法もあるのは知っていたがあまり使っていない.
RECT rect = { 0 } ;
K & R 2nd の A8.7 に書かれている.
Web で検索すると ” RECT rect = { } ; ” の様な記述もあったが,これはどうかと…
構造体のコピーや戻り値は悩む所.
RECT の様な単純な構造では特に問題ないと思う.
XML などのツリー構造の場合はデータにより時間がかかるので注意が必要.
2020/10/13
次の様なコードで動作 を確認.
struct strct_c { i__8 i1 ; i_32 i4 ; i_16 i2 ; i_64 i8 ; } ; bool test_struct (void) { strct_a sa_rn ; strct_b sb_rn ; strct_c sc_rn ; strct_a sa_f0 = {1,2,3,4} ; strct_b sb_f0 = {1,2,3,4} ; strct_c sc_f0 = {1,2,3,4} ; strct_a sa__0 = {0} ; strct_b sb__0 = {0} ; strct_c sc__0 = {0} ; strct_a sa_m0 ; memset(&sa_m0,0,sizeof(sa_m0)) ; strct_b sb_m0 ; memset(&sb_m0,0,sizeof(sb_m0)) ; strct_c sc_m0 ; memset(&sc_m0,0,sizeof(sc_m0)) ; ::dump_mem(&sc_rn,sizeof(sc_rn)) ; ::dump_mem(&sc_f0,sizeof(sc_f0)) ; ::dump_mem(&sc__0,sizeof(sc__0)) ; ::dump_mem(&sc_m0,sizeof(sc_m0)) ; return true ; }