Frost Moon Project

MinGWで_tmain()を使用する方法 - Frost Moon Project アクセスランキング

Home > Tips > MinGWで_tmain()を使用する方法

MinGWで_tmain()を使用する方法

  1. 問題
  2. 解決方法

問題
現在、MinGWではワイド文字引数を扱うwmain()を使用することが出来ません。
これはtchar.hにもあるように、Unicode用のスタートアップモジュールが実装されていない為です。
tchar.h
1
2
3
4
5
6
7
8
/*  for porting from other Windows compilers */
#if 0  /* no  wide startup module */
#define _tmain      wmain
#define _tWinMain   wWinMain
#define _tenviron   _wenviron
#define __targv     __wargv
#endif
        


以下は_tmain()に渡された引数argvを表示するだけのコードですが、
UNICODEビルドの為、エラーが出てしまいます。
引数argvを表示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define UNICODE
#define _UNICODE
 
 
#include <windows.h>
#include <tchar.h>
 
int _tmain(int argc,TCHAR* argv[]){
    for(int i=0;i<argc;i++){
        MessageBox(NULL,argv[i],NULL,MB_OK);
    }
    return 0;
}
 
        



C:\msys\home\Owner\works>g++ tmain.cpp -o tmain
c:/msys/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../libmingw32.a(main.o): In function `main':
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'
collect2: ld returned 1 exit status


そこで、考えられるのはCommandLineToArgvW()GetCommandLine()の組み合わせで引数を取得する方法です。
CommandLineToArgvW()+GetCommandLine()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define UNICODE
#define _UNICODE
 
 
#include<windows.h>
#include<tchar.h>
 
int main(){
    wchar_t** argv;
    int argc=0;
 
    argv=CommandLineToArgvW(GetCommandLine(),&argc);
 
    for(int i=0;i<argc;i++){
        MessageBox(NULL,argv[i],_T("CommandLineToArgvW()+GetCommandLine()"),MB_OK);
    }
 
    LocalFree(argv);
 
    return 0;
}
        


しかし、この方法ではワイルドカードが展開されません。


ANSIビルドのmain()と同じように展開出来ないものでしょうか?
解決方法
MinGWで引数のワイルドカードが展開されてしまうのを防ぐ方法にも登場した__getmainargs()/__wgetmainargs()を使用します。
__getmainargs()/__wgetmainargs()は引数の_DoWildCardを1とすることで、ワイルドカードの展開を行うことが出来ます。
int __wgetmainargs(
int * _Argc,
wchar_t *** _Argv,
wchar_t *** _Env,
int _DoWildCard,
_startupinfo * _StartInfo);


今回は_UNICODEが定義されているかどうかで処理を分岐することでANSI/UNICODEビルドのどちらでも利用できるようになっています。
念願の_tmain()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#define UNICODE
#define _UNICODE
 
 
#include <windows.h>
#include <tchar.h>
 
#undef _tmain
#ifdef _UNICODE
#define _tmain wmain
#else
#define _tmain main
#endif
 
#ifdef __cplusplus
extern "C"
#endif
 
void __wgetmainargs(int*,wchar_t***,wchar_t***,int,int*);
 
int wmain(int argc, wchar_t *argv[]);
 
int _tmain(int argc,TCHAR* argv[]){
    for(int i=0;i<argc;i++){
        MessageBox(NULL,argv[i],_T("__wgetmainargs()"),MB_OK);
    }
    return 0;
}
 
#ifdef _UNICODE
int main(){
    wchar_t** argv;
    wchar_t** enpv;
    int argc=0,si=0;
    __wgetmainargs(&argc,&argv,&enpv,1,&si);
    return wmain(argc,argv);
}
#endif
 
        


無事、ワイルドカードの展開を行う_tmain()を使用することが出来ました。


因みに、展開するかどうかMinGWに任せる場合は"extern int _CRT_glob;"を適当な行に追加し、
_DoWildCardの部分を_CRT_globとします。
関連Tips
MinGWで引数のワイルドカードが展開されてしまうのを防ぐ方法

Copyright(C) 2007-2025 Frost Moon Project


Home > Tips > MinGWで_tmain()を使用する方法