1. Hello, Haxe World!

    Posted on 3月 21st, 2013 by cx20

    Haxe

    Haxe は静的型付けを特徴としたオブジェクト指向言語である。Neko VM 形式の他、JavaScript、C++、PHP、Java、C# 等に変換することが可能となっている。

    ソースコード(Haxe)

    class Hello {
        static function main() {
            trace("Hello, Haxe World!");
        }
    }

    上記コードを JavaScript に変換した場合、以下のコードが生成される。

    ソースコード(JavaScript)

    var Hello = function() { }
    Hello.__name__ = true;
    Hello.main = function() {
        console.log("Hello, Haxe World!");
    }
    var HxOverrides = function() { }
    HxOverrides.__name__ = true;
    HxOverrides.dateStr = function(date) {
        var m = date.getMonth() + 1;
        var d = date.getDate();
        var h = date.getHours();
        var mi = date.getMinutes();
        var s = date.getSeconds();
        return date.getFullYear() + "-" + (m < 10?"0" + m:"" + m) + "-" + (d < 10?"0" + d:"" + d) + " " + (h < 10?"0" + h:"" + h) + ":" + (mi < 10?"0" + mi:"" + mi) + ":" + (s < 10?"0" + s:"" + s);
    }
    HxOverrides.strDate = function(s) {
        switch(s.length) {
        case 8:
            var k = s.split(":");
            var d = new Date();
            d.setTime(0);
            d.setUTCHours(k[0]);
            d.setUTCMinutes(k[1]);
            d.setUTCSeconds(k[2]);
            return d;
        case 10:
            var k = s.split("-");
            return new Date(k[0],k[1] - 1,k[2],0,0,0);
        case 19:
            var k = s.split(" ");
            var y = k[0].split("-");
            var t = k[1].split(":");
            return new Date(y[0],y[1] - 1,y[2],t[0],t[1],t[2]);
        default:
            throw "Invalid date format : " + s;
        }
    }
    HxOverrides.cca = function(s,index) {
        var x = s.charCodeAt(index);
        if(x != x) return undefined;
        return x;
    }
    HxOverrides.substr = function(s,pos,len) {
        if(pos != null && pos != 0 && len != null && len < 0) return "";
        if(len == null) len = s.length;
        if(pos < 0) {
            pos = s.length + pos;
            if(pos < 0) pos = 0;
        } else if(len < 0) len = s.length + len - pos;
        return s.substr(pos,len);
    }
    HxOverrides.remove = function(a,obj) {
        var i = 0;
        var l = a.length;
        while(i < l) {
            if(a[i] == obj) {
                a.splice(i,1);
                return true;
            }
            i++;
        }
        return false;
    }
    HxOverrides.iter = function(a) {
        return { cur : 0, arr : a, hasNext : function() {
            return this.cur < this.arr.length;
        }, next : function() {
            return this.arr[this.cur++];
        }};
    }
    var IntIter = function(min,max) {
        this.min = min;
        this.max = max;
    };
    IntIter.__name__ = true;
    IntIter.prototype = {
        next: function() {
            return this.min++;
        }
        ,hasNext: function() {
            return this.min < this.max;
        }
        ,__class__: IntIter
    }
    var Std = function() { }
    Std.__name__ = true;
    Std["is"] = function(v,t) {
        return js.Boot.__instanceof(v,t);
    }
    Std.string = function(s) {
        return js.Boot.__string_rec(s,"");
    }
    Std["int"] = function(x) {
        return x | 0;
    }
    Std.parseInt = function(x) {
        var v = parseInt(x,10);
        if(v == 0 && (HxOverrides.cca(x,1) == 120 || HxOverrides.cca(x,1) == 88)) v = parseInt(x);
        if(isNaN(v)) return null;
        return v;
    }
    Std.parseFloat = function(x) {
        return parseFloat(x);
    }
    Std.random = function(x) {
        return Math.floor(Math.random() * x);
    }
    var js = js || {}
    js.Boot = function() { }
    js.Boot.__name__ = true;
    js.Boot.__unhtml = function(s) {
        return s.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
    }
    js.Boot.__trace = function(v,i) {
        var msg = i != null?i.fileName + ":" + i.lineNumber + ": ":"";
        msg += js.Boot.__string_rec(v,"");
        var d;
        if(typeof(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null) d.innerHTML += js.Boot.__unhtml(msg) + "<br/>"; else if(typeof(console) != "undefined" && console.log != null) console.log(msg);
    }
    js.Boot.__clear_trace = function() {
        var d = document.getElementById("haxe:trace");
        if(d != null) d.innerHTML = "";
    }
    js.Boot.isClass = function(o) {
        return o.__name__;
    }
    js.Boot.isEnum = function(e) {
        return e.__ename__;
    }
    js.Boot.getClass = function(o) {
        return o.__class__;
    }
    js.Boot.__string_rec = function(o,s) {
        if(o == null) return "null";
        if(s.length >= 5) return "<...>";
        var t = typeof(o);
        if(t == "function" && (o.__name__ || o.__ename__)) t = "object";
        switch(t) {
        case "object":
            if(o instanceof Array) {
                if(o.__enum__) {
                    if(o.length == 2) return o[0];
                    var str = o[0] + "(";
                    s += "t";
                    var _g1 = 2, _g = o.length;
                    while(_g1 < _g) {
                        var i = _g1++;
                        if(i != 2) str += "," + js.Boot.__string_rec(o[i],s); else str += js.Boot.__string_rec(o[i],s);
                    }
                    return str + ")";
                }
                var l = o.length;
                var i;
                var str = "[";
                s += "t";
                var _g = 0;
                while(_g < l) {
                    var i1 = _g++;
                    str += (i1 > 0?",":"") + js.Boot.__string_rec(o[i1],s);
                }
                str += "]";
                return str;
            }
            var tostr;
            try {
                tostr = o.toString;
            } catch( e ) {
                return "???";
            }
            if(tostr != null && tostr != Object.toString) {
                var s2 = o.toString();
                if(s2 != "[object Object]") return s2;
            }
            var k = null;
            var str = "{n";
            s += "t";
            var hasp = o.hasOwnProperty != null;
            for( var k in o ) { ;
            if(hasp && !o.hasOwnProperty(k)) {
                continue;
            }
            if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__") {
                continue;
            }
            if(str.length != 2) str += ", n";
            str += s + k + " : " + js.Boot.__string_rec(o[k],s);
            }
            s = s.substring(1);
            str += "n" + s + "}";
            return str;
        case "function":
            return "<function>";
        case "string":
            return o;
        default:
            return String(o);
        }
    }
    js.Boot.__interfLoop = function(cc,cl) {
        if(cc == null) return false;
        if(cc == cl) return true;
        var intf = cc.__interfaces__;
        if(intf != null) {
            var _g1 = 0, _g = intf.length;
            while(_g1 < _g) {
                var i = _g1++;
                var i1 = intf[i];
                if(i1 == cl || js.Boot.__interfLoop(i1,cl)) return true;
            }
        }
        return js.Boot.__interfLoop(cc.__super__,cl);
    }
    js.Boot.__instanceof = function(o,cl) {
        try {
            if(o instanceof cl) {
                if(cl == Array) return o.__enum__ == null;
                return true;
            }
            if(js.Boot.__interfLoop(o.__class__,cl)) return true;
        } catch( e ) {
            if(cl == null) return false;
        }
        switch(cl) {
        case Int:
            return Math.ceil(o%2147483648.0) === o;
        case Float:
            return typeof(o) == "number";
        case Bool:
            return o === true || o === false;
        case String:
            return typeof(o) == "string";
        case Dynamic:
            return true;
        default:
            if(o == null) return false;
            if(cl == Class && o.__name__ != null) return true; else null;
            if(cl == Enum && o.__ename__ != null) return true; else null;
            return o.__enum__ == cl;
        }
    }
    js.Boot.__cast = function(o,t) {
        if(js.Boot.__instanceof(o,t)) return o; else throw "Cannot cast " + Std.string(o) + " to " + Std.string(t);
    }
    if(Array.prototype.indexOf) HxOverrides.remove = function(a,o) {
        var i = a.indexOf(o);
        if(i == -1) return false;
        a.splice(i,1);
        return true;
    }; else null;
    Math.__name__ = ["Math"];
    Math.NaN = Number.NaN;
    Math.NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY;
    Math.POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
    Math.isFinite = function(i) {
        return isFinite(i);
    };
    Math.isNaN = function(i) {
        return isNaN(i);
    };
    String.prototype.__class__ = String;
    String.__name__ = true;
    Array.prototype.__class__ = Array;
    Array.__name__ = true;
    Date.prototype.__class__ = Date;
    Date.__name__ = ["Date"];
    var Int = { __name__ : ["Int"]};
    var Dynamic = { __name__ : ["Dynamic"]};
    var Float = Number;
    Float.__name__ = ["Float"];
    var Bool = Boolean;
    Bool.__ename__ = ["Bool"];
    var Class = { __name__ : ["Class"]};
    var Enum = { };
    var Void = { __ename__ : ["Void"]};
    Hello.main();

    実行方法(Neko VM による実行例)

    C:¥> haxe -main Hello -neko Hello.n
    C:¥> neko Hello.n

    実行方法(Node.js による実行例)

    C:¥> haxe -main Hello -js Hello.js
    C:¥> node Hello.js

    実行結果

    Hello, Haxe World!
  2. Hello, Win32 API(Oxygene) World!

    Posted on 3月 20th, 2013 by cx20

    Win32 API(Oxygene)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Oxygene にて SWT の非公開 API を使用した Win32 API 呼出しの例となっている。

    ソースコード

    namespace hello;
     
    interface
    uses
        org.eclipse.swt.internal.win32.*;
     
    type
        Hello = class
    public
        class method Main(args: array of String);
    end;
     
    implementation
     
    class method Hello.Main(args: array of String);
    var
        lpText: TCHAR;
        lpCaption: TCHAR;
    begin
        lpText := new TCHAR(0, "Hello, Win32 API World!", True);
        lpCaption := new TCHAR(0, "Hello, World", True);
        OS.MessageBox(0, lpText, lpCaption, OS.MB_OK );
     
    end;
     
    end.

    コンパイル&実行方法

    C:¥> oxygene Hello.pas -ref:rt.jar;org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar -mode:Java
    C:¥> java -Xbootclasspath/a:org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar -jar hello.jar

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API World!
    ---------------------------
    OK   
    ---------------------------
  3. Hello, JSX World!

    Posted on 3月 20th, 2013 by cx20

    JSX

    JSX は DeNA により開発された静的型付けを特徴としたスクリプト言語である。JavaScript にコンパイルすることが可能となっている。

    ソースコード(JSX)

    class _Main {
        static function main(args : string[]) :void {
            log "Hello, JSX World!";
        }
    }

    上記コードを JavaScript にコンパイルした場合、以下のコードが生成される。

    ソースコード(JavaScript)

    #!/usr/local/Cellar/node/0.6.6/bin/node
    // generatedy by JSX compiler 0.9.2 (2013-01-30 11:14:28 +0900; 1a8b01b71633517541daa97862da204a2005c8aa)
    var JSX = {};
    (function () {
     
    /**
     * copies the implementations from source interface to target
     */
    function $__jsx_merge_interface(target, source) {
    	for (var k in source.prototype)
    		if (source.prototype.hasOwnProperty(k))
    			target.prototype[k] = source.prototype[k];
    }
     
    /**
     * defers the initialization of the property
     */
    function $__jsx_lazy_init(obj, prop, func) {
    	function reset(obj, prop, value) {
    		delete obj[prop];
    		obj[prop] = value;
    		return value;
    	}
     
    	Object.defineProperty(obj, prop, {
    		get: function () {
    			return reset(obj, prop, func());
    		},
    		set: function (v) {
    			reset(obj, prop, v);
    		},
    		enumerable: true,
    		configurable: true
    	});
    }
     
    /**
     * sideeffect().a /= b
     */
    function $__jsx_div_assign(obj, prop, divisor) {
    	return obj[prop] = (obj[prop] / divisor) | 0;
    }
     
    /*
     * global functions called by JSX
     * (enamed so that they do not conflict with local variable names)
     */
    var $__jsx_parseInt = parseInt;
    var $__jsx_parseFloat = parseFloat;
    var $__jsx_isNaN = isNaN;
    var $__jsx_isFinite = isFinite;
     
    var $__jsx_encodeURIComponent = encodeURIComponent;
    var $__jsx_decodeURIComponent = decodeURIComponent;
    var $__jsx_encodeURI = encodeURI;
    var $__jsx_decodeURI = decodeURI;
     
    var $__jsx_ObjectToString = Object.prototype.toString;
    var $__jsx_ObjectHasOwnProperty = Object.prototype.hasOwnProperty;
     
    /*
     * profiler object, initialized afterwards
     */
    function $__jsx_profiler() {
    }
     
    /*
     * public interface to JSX code
     */
    JSX.require = function (path) {
    	var m = $__jsx_classMap[path];
    	return m !== undefined ? m : null;
    };
     
    JSX.profilerIsRunning = function () {
    	return $__jsx_profiler.getResults != null;
    };
     
    JSX.getProfileResults = function () {
    	return ($__jsx_profiler.getResults || function () { return {}; })();
    };
     
    JSX.postProfileResults = function (url) {
    	if ($__jsx_profiler.postResults == null)
    		throw new Error("profiler has not been turned on");
    	return $__jsx_profiler.postResults(url);
    };
     
    JSX.resetProfileResults = function () {
    	if ($__jsx_profiler.resetResults == null)
    		throw new Error("profiler has not been turned on");
    	return $__jsx_profiler.resetResults();
    };
    /**
     * class _Main extends Object
     * @constructor
     */
    function _Main() {
    }
     
    _Main.prototype = new Object;
    /**
     * @constructor
     */
    function _Main$() {
    };
     
    _Main$.prototype = new _Main;
     
    /**
     * @param {Array.<undefined|!string>} args
     */
    _Main.main$AS = function (args) {
    	console.log("Hello, JSX World!");
    };
     
    var _Main$main$AS = _Main.main$AS;
     
    var $__jsx_classMap = {
    	"hello.jsx": {
    		_Main: _Main,
    		_Main$: _Main$
    	}
    };
     
     
    /**
     * launches _Main.main(:string[]):void invoked by jsx --run|--executable
     */
    JSX.runMain = function (sourceFile, args) {
    	var module = JSX.require(sourceFile);
     
    	if (! module._Main) {
    		throw new Error("entry point _Main not found in " + sourceFile);
    	}
    	if (! module._Main.main$AS) {
    		throw new Error("entry point _Main.main(:string[]):void not found in " + sourceFile);
    	}
    	module._Main.main$AS(args);
    };
     
    /**
     * launches _Test#test*():void invoked by jsx --test
     */
    JSX.runTests = function (sourceFile, tests) {
    	var module = JSX.require(sourceFile);
    	var testClass = module._Test$;
     
    	if (!testClass) return; // skip if there's no test class
     
    	if(tests.length === 0) {
    		var p = testClass.prototype;
    		for (var m in p) {
    			if (p[m] instanceof Function
    				&& /^test.*[$]$/.test(m)) {
    				tests.push(m);
    			}
    		}
    	}
    	else { // set as process arguments
    		tests = tests.map(function (name) {
    			return name + "$"; // mangle for function test*():void
    		});
    	}
     
    	var testCase = new testClass();
     
    	if (testCase.beforeClass$AS != null)
    		testCase.beforeClass$AS(tests);
     
    	for (var i = 0; i < tests.length; ++i) {
    		(function (method) {
    			if (method in testCase) {
    				testCase.run$SF$V$(method, function() { testCase[method](); });
    			}
    			else {
    				throw new ReferenceError("No such test method: " + method);
    			}
    		}(tests[i]));
    	}
     
    	if (testCase.afterClass$ != null)
    		testCase.afterClass$();
    };
    JSX.runMain("hello.jsx", process.argv.slice(2))
    })();

    実行方法(JSX による実行例)

    C:¥> jsx --run hello.jsx

    実行方法(Node.js による実行例)

    $ jsx --executable node --output hello.jsx.js hello.jsx
    $ node hello.jsx.js

    実行結果

    Hello, JSX World!
  4. Hello, Win32 GUI(BeanShell) World!

    Posted on 3月 19th, 2013 by cx20

    Win32 GUI(BeanShell)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は BeanShell にて Java の GUI ツールキット SWT の非公開 API を使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    import org.eclipse.swt.internal.Callback;
    import org.eclipse.swt.internal.win32.MSG;
    import org.eclipse.swt.internal.win32.OS;
    import org.eclipse.swt.internal.win32.PAINTSTRUCT;
    import org.eclipse.swt.internal.win32.RECT;
    import org.eclipse.swt.internal.win32.TCHAR;
    import org.eclipse.swt.internal.win32.WNDCLASS;
     
    public class Hello {
        public static int WndProc(int hWnd, int uMsg, int wParam, int lParam) {
            int hdc;
            PAINTSTRUCT lpPaint = new PAINTSTRUCT();
            String strMessage = "Hello, Win32 GUI(SWT) World!";
     
            switch (uMsg) {
            case OS.WM_PAINT:
                RECT rect = new RECT();
                hdc = OS.BeginPaint(hWnd, lpPaint);
                OS.GetClientRect(hWnd, rect);
                OS.DrawTextW(hdc, strMessage.toCharArray(), strMessage.length(), rect, OS.DT_SINGLELINE);
                OS.EndPaint(hWnd, lpPaint);
                return 0;
            case OS.WM_DESTROY:
                System.exit(wParam);
            default:
                return OS.DefWindowProc(hWnd, uMsg, wParam, lParam);
            }
        }
     
        public static void WinMain(String[] args) {
            int hInstance = OS.GetModuleHandle(null);
            TCHAR className  = new TCHAR(0, "helloWindow", true);
            TCHAR windowName = new TCHAR(0, "Hello, World", true);
     
            WNDCLASS wc      = new WNDCLASS();
            wc.style         = OS.CS_HREDRAW | OS.CS_VREDRAW;
            wc.lpfnWndProc   = new Callback(Hello.class, "WndProc", 4).getAddress();
            wc.hInstance     = hInstance;
            wc.hCursor       = OS.LoadCursor(0, OS.IDC_ARROW);
            wc.hbrBackground = OS.GetStockObject(OS.COLOR_WINDOW + 1 );
            wc.lpszClassName = OS.HeapAlloc(OS.GetProcessHeap(), OS.HEAP_ZERO_MEMORY, className.length() * 2);
            OS.MoveMemory(wc.lpszClassName, className, className.length() * 2);
     
            OS.RegisterClass(wc);
     
            int hWnd = OS.CreateWindowEx(
                0,
                className,
                windowName,
                OS.WS_OVERLAPPEDWINDOW,
                OS.CW_USEDEFAULT, 
                OS.CW_USEDEFAULT,
                640,
                480,
                0,
                0,
                hInstance,
                null);
     
            OS.ShowWindow(hWnd, OS.SW_SHOW);
            OS.UpdateWindow(hWnd);
     
            MSG lpMsg = new MSG();
            while (OS.GetMessage(lpMsg, 0, 0, 0)) {
                OS.TranslateMessage(lpMsg);
                OS.DispatchMessage(lpMsg);
            }
        }
     
        public static void main(String[] args) {
            WinMain( args );
        }
     
    }

    コンパイル&実行方法

    C:¥> SET CLASSPATH=bsh-2.0b4.jar;org.eclipse.swt.win32.win32.x86_3.6.1.v3655c.jar;%CLASSPATH%
    C:¥> java bsh.Interpreter Hello.bsh

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(SWT) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  5. Hello, COM(GAS) World!

    Posted on 3月 18th, 2013 by cx20

    COM(GAS)

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は GAS による COM クライアントの例となっている。

    ソースコード

            .file   "hello.c"
            .def    ___main;        .scl    2;      .type   32;     .endef
            .section .rdata,"dr"
            .align 4
    LC0:
            .ascii "B

    上記コードは以下のC言語のソースを GCC でアセンブリコード出力(gcc -s hello.c)したものに相当する。

    #include <ole2.h>
     
    int main( int argc, char* argv[] )
    {
        CLSID clsid;
        IDispatch* pShell;
        IDispatch* pFolder;
        DISPID dispid;
        OLECHAR* ptName = L"BrowseForFolder";
        DISPPARAMS param = { NULL, NULL, 0, 0 };
        VARIANT varg[4];
        VARIANT vResult;
     
        CoInitialize( NULL );
     
        CLSIDFromProgID(L"Shell.Application", &clsid );
        CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell);
        pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid );
     
        VariantInit( &varg[0] );
        varg[0].vt = VT_I4;
        varg[0].lVal = 36L;  /* ssfWINDOWS */
     
        VariantInit( &varg[1] );
        varg[1].vt = VT_I4;
        varg[1].lVal = 0L;
     
        VariantInit( &varg[2] );
        varg[2].vt = VT_BSTR;
        varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); 
     
        VariantInit( &varg[3] );
        varg[3].vt = VT_I4;
        varg[3].lVal = 0L;
     
        param.cArgs = 4;
        param.rgvarg = varg;
     
        pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &param, &vResult, NULL, NULL );
     
        VariantInit( &varg[0] );
        VariantInit( &varg[1] );
        VariantInit( &varg[2] );
        VariantInit( &varg[3] );
     
        pFolder = V_DISPATCH( &vResult );
        if ( pFolder != NULL )
        {
            pFolder->lpVtbl->Release( (void*)pFolder );
        }
        pShell->lpVtbl->Release( (void*)pShell );
     
        CoUninitialize();
     
        return 0;
    }

    コンパイル&リンク方法

    C:¥> gcc -c hello.c
    C:¥> gcc -o hello hello.o -l ole32  -l oleaut32 -l uuid

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM Wolrd!                      |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+
  6. Hello, COM(LLVM) World!

    Posted on 3月 17th, 2013 by cx20

    COM(LLVM)

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は LLVM Assembler による COM クライアントの例となっている。

    ソースコード

    ; ModuleID = 'hello.c'
    target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
    target triple = "i686-w64-mingw32"
     
    %struct._GUID = type { i32, i16, i16, [8 x i8] }
    %struct.IDispatch = type { %struct.IDispatchVtbl* }
    %struct.IDispatchVtbl = type { i32 (%struct.IDispatch*, %struct._GUID*, i8**)*, i32 (%struct.IDispatch*)*, i32 (%struct.IDispatch*)*, i32 (%struct.IDispatch*, i32*)*, i32 (%struct.IDispatch*, i32, i32, %struct.ITypeInfo**)*, i32 (%struct.IDispatch*, %struct._GUID*, i16**, i32, i32, i32*)*, i32 (%struct.IDispatch*, i32, %struct._GUID*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)* }
    %struct.ITypeInfo = type { %struct.ITypeInfoVtbl* }
    %struct.ITypeInfoVtbl = type { i32 (%struct.ITypeInfo*, %struct._GUID*, i8**)*, i32 (%struct.ITypeInfo*)*, i32 (%struct.ITypeInfo*)*, i32 (%struct.ITypeInfo*, %struct.tagTYPEATTR**)*, i32 (%struct.ITypeInfo*, %struct.ITypeComp**)*, i32 (%struct.ITypeInfo*, i32, %struct.tagFUNCDESC**)*, i32 (%struct.ITypeInfo*, i32, %struct.tagVARDESC**)*, i32 (%struct.ITypeInfo*, i32, i16**, i32, i32*)*, i32 (%struct.ITypeInfo*, i32, i32*)*, i32 (%struct.ITypeInfo*, i32, i32*)*, i32 (%struct.ITypeInfo*, i16**, i32, i32*)*, i32 (%struct.ITypeInfo*, i8*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)*, i32 (%struct.ITypeInfo*, i32, i16**, i16**, i32*, i16**)*, i32 (%struct.ITypeInfo*, i32, i32, i16**, i16**, i16*)*, i32 (%struct.ITypeInfo*, i32, %struct.ITypeInfo**)*, i32 (%struct.ITypeInfo*, i32, i32, i8**)*, i32 (%struct.ITypeInfo*, %struct.IUnknown*, %struct._GUID*, i8**)*, i32 (%struct.ITypeInfo*, i32, i16**)*, i32 (%struct.ITypeInfo*, %struct.ITypeLib**, i32*)*, void (%struct.ITypeInfo*, %struct.tagTYPEATTR*)*, void (%struct.ITypeInfo*, %struct.tagFUNCDESC*)*, void (%struct.ITypeInfo*, %struct.tagVARDESC*)* }
    %struct.tagTYPEATTR = type <{ %struct._GUID, i32, i32, i32, i32, i16*, i32, i32, i16, i16, i16, i16, i16, i16, i16, i16, %struct.tagTYPEDESC, %struct.tagIDLDESC }>
    %struct.tagTYPEDESC = type <{ %union.anon, i16, [2 x i8] }>
    %union.anon = type { %struct.tagTYPEDESC* }
    %struct.tagIDLDESC = type { i32, i16 }
    %struct.ITypeComp = type { %struct.ITypeCompVtbl* }
    %struct.ITypeCompVtbl = type { i32 (%struct.ITypeComp*, %struct._GUID*, i8**)*, i32 (%struct.ITypeComp*)*, i32 (%struct.ITypeComp*)*, i32 (%struct.ITypeComp*, i16*, i32, i16, %struct.ITypeInfo**, i32*, %union.tagBINDPTR*)*, i32 (%struct.ITypeComp*, i16*, i32, %struct.ITypeInfo**, %struct.ITypeComp**)* }
    %union.tagBINDPTR = type { %struct.tagFUNCDESC* }
    %struct.tagFUNCDESC = type <{ i32, i32*, %struct.tagELEMDESC*, i32, i32, i32, i16, i16, i16, i16, %struct.tagELEMDESC, i16, [2 x i8] }>
    %struct.tagELEMDESC = type <{ %struct.tagTYPEDESC, %union.anon.0 }>
    %union.anon.0 = type { %struct.tagIDLDESC }
    %struct.tagVARDESC = type <{ i32, i16*, %union.anon.9, %struct.tagELEMDESC, i16, [2 x i8], i32 }>
    %union.anon.9 = type { i32 }
    %struct.tagDISPPARAMS = type { %struct.tagVARIANT*, i32*, i32, i32 }
    %struct.tagVARIANT = type { %union.anon.1 }
    %union.anon.1 = type { %struct.anon }
    %struct.anon = type { i16, i16, i16, i16, %union.anon.2 }
    %union.anon.2 = type { i64 }
    %struct.tagEXCEPINFO = type { i16, i16, i16*, i16*, i16*, i32, i8*, i32 (%struct.tagEXCEPINFO*)*, i32 }
    %struct.IUnknown = type { %struct.IUnknownVtbl* }
    %struct.IUnknownVtbl = type { i32 (%struct.IUnknown*, %struct._GUID*, i8**)*, i32 (%struct.IUnknown*)*, i32 (%struct.IUnknown*)* }
    %struct.ITypeLib = type { %struct.ITypeLibVtbl* }
    %struct.ITypeLibVtbl = type { i32 (%struct.ITypeLib*, %struct._GUID*, i8**)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*, i32, %struct.ITypeInfo**)*, i32 (%struct.ITypeLib*, i32, i32*)*, i32 (%struct.ITypeLib*, %struct._GUID*, %struct.ITypeInfo**)*, i32 (%struct.ITypeLib*, %struct.tagTLIBATTR**)*, i32 (%struct.ITypeLib*, %struct.ITypeComp**)*, i32 (%struct.ITypeLib*, i32, i16**, i16**, i32*, i16**)*, i32 (%struct.ITypeLib*, i16*, i32, i32*)*, i32 (%struct.ITypeLib*, i16*, i32, %struct.ITypeInfo**, i32*, i16*)*, void (%struct.ITypeLib*, %struct.tagTLIBATTR*)* }
    %struct.tagTLIBATTR = type <{ %struct._GUID, i32, i32, i16, i16, i16, [2 x i8] }>
     
    @.str = private unnamed_addr constant [16 x i16] [i16 66, i16 114, i16 111, i16 119, i16 115, i16 101, i16 70, i16 111, i16 114, i16 70, i16 111, i16 108, i16 100, i16 101, i16 114, i16 0], align 2
    @.str1 = private unnamed_addr constant [18 x i16] [i16 83, i16 104, i16 101, i16 108, i16 108, i16 46, i16 65, i16 112, i16 112, i16 108, i16 105, i16 99, i16 97, i16 116, i16 105, i16 111, i16 110, i16 0], align 2
    @IID_IDispatch = external constant %struct._GUID
    @GUID_NULL = external constant %struct._GUID
    @.str2 = private unnamed_addr constant [18 x i16] [i16 72, i16 101, i16 108, i16 108, i16 111, i16 44, i16 32, i16 67, i16 79, i16 77, i16 32, i16 87, i16 111, i16 114, i16 108, i16 100, i16 33, i16 0], align 2
     
    define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
      %clsid = alloca %struct._GUID, align 4
      %pShell = alloca %struct.IDispatch*, align 4
      %dispid = alloca i32, align 4
      %ptName = alloca i16*, align 4
      %param = alloca %struct.tagDISPPARAMS, align 4
      %varg = alloca [4 x %struct.tagVARIANT], align 8
      %vResult = alloca %struct.tagVARIANT, align 8
      store i16* getelementptr inbounds ([16 x i16]* @.str, i32 0, i32 0), i16** %ptName, align 4, !tbaa !0
      %1 = bitcast %struct.tagDISPPARAMS* %param to i8*
      call void @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 16, i32 4, i1 false)
      %2 = call x86_stdcallcc i32 @CoInitialize(i8* null) nounwind
      %3 = call x86_stdcallcc i32 @CLSIDFromProgID(i16* getelementptr inbounds ([18 x i16]* @.str1, i32 0, i32 0), %struct._GUID* %clsid) nounwind
      %4 = bitcast %struct.IDispatch** %pShell to i8**
      %5 = call x86_stdcallcc i32 @CoCreateInstance(%struct._GUID* %clsid, %struct.IUnknown* null, i32 1, %struct._GUID* @IID_IDispatch, i8** %4) nounwind
      %6 = load %struct.IDispatch** %pShell, align 4, !tbaa !0
      %7 = getelementptr inbounds %struct.IDispatch* %6, i32 0, i32 0
      %8 = load %struct.IDispatchVtbl** %7, align 4, !tbaa !0
      %9 = getelementptr inbounds %struct.IDispatchVtbl* %8, i32 0, i32 5
      %10 = load i32 (%struct.IDispatch*, %struct._GUID*, i16**, i32, i32, i32*)** %9, align 4, !tbaa !0
      %11 = call x86_stdcallcc i32 @GetUserDefaultLCID() nounwind
      %12 = call x86_stdcallcc i32 %10(%struct.IDispatch* %6, %struct._GUID* @GUID_NULL, i16** %ptName, i32 1, i32 %11, i32* %dispid) nounwind
      %13 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %13) nounwind
      %14 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0, i32 0, i32 0, i32 0
      store i16 3, i16* %14, align 8, !tbaa !3
      %15 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0, i32 0, i32 0, i32 4
      %16 = bitcast %union.anon.2* %15 to i32*
      store i32 36, i32* %16, align 8, !tbaa !4
      %17 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 1
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %17) nounwind
      %18 = getelementptr inbounds %struct.tagVARIANT* %17, i32 0, i32 0, i32 0, i32 0
      store i16 3, i16* %18, align 8, !tbaa !3
      %19 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 1, i32 0, i32 0, i32 4
      %20 = bitcast %union.anon.2* %19 to i32*
      store i32 0, i32* %20, align 8, !tbaa !4
      %21 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 2
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %21) nounwind
      %22 = getelementptr inbounds %struct.tagVARIANT* %21, i32 0, i32 0, i32 0, i32 0
      store i16 8, i16* %22, align 8, !tbaa !3
      %23 = call x86_stdcallcc i16* @SysAllocString(i16* getelementptr inbounds ([18 x i16]* @.str2, i32 0, i32 0)) nounwind
      %24 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 2, i32 0, i32 0, i32 4
      %25 = bitcast %union.anon.2* %24 to i16**
      store i16* %23, i16** %25, align 8, !tbaa !0
      %26 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 3
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %26) nounwind
      %27 = getelementptr inbounds %struct.tagVARIANT* %26, i32 0, i32 0, i32 0, i32 0
      store i16 3, i16* %27, align 8, !tbaa !3
      %28 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 3, i32 0, i32 0, i32 4
      %29 = bitcast %union.anon.2* %28 to i32*
      store i32 0, i32* %29, align 8, !tbaa !4
      %30 = getelementptr inbounds %struct.tagDISPPARAMS* %param, i32 0, i32 2
      store i32 4, i32* %30, align 4, !tbaa !5
      %31 = getelementptr inbounds %struct.tagDISPPARAMS* %param, i32 0, i32 0
      store %struct.tagVARIANT* %13, %struct.tagVARIANT** %31, align 4, !tbaa !0
      %32 = load %struct.IDispatch** %pShell, align 4, !tbaa !0
      %33 = getelementptr inbounds %struct.IDispatch* %32, i32 0, i32 0
      %34 = load %struct.IDispatchVtbl** %33, align 4, !tbaa !0
      %35 = getelementptr inbounds %struct.IDispatchVtbl* %34, i32 0, i32 6
      %36 = load i32 (%struct.IDispatch*, i32, %struct._GUID*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)** %35, align 4, !tbaa !0
      %37 = load i32* %dispid, align 4, !tbaa !4
      %38 = call x86_stdcallcc i32 @GetUserDefaultLCID() nounwind
      %39 = call x86_stdcallcc i32 %36(%struct.IDispatch* %32, i32 %37, %struct._GUID* @GUID_NULL, i32 %38, i16 zeroext 1, %struct.tagDISPPARAMS* %param, %struct.tagVARIANT* %vResult, %struct.tagEXCEPINFO* null, i32* null) nounwind
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %13) nounwind
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %17) nounwind
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %21) nounwind
      call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %26) nounwind
      %40 = getelementptr inbounds %struct.tagVARIANT* %vResult, i32 0, i32 0, i32 0, i32 4
      %41 = bitcast %union.anon.2* %40 to %struct.IDispatch**
      %42 = load %struct.IDispatch** %41, align 8, !tbaa !0
      %43 = icmp eq %struct.IDispatch* %42, null
      br i1 %43, label %50, label %44
     
    ; <label>:44                                      ; preds = %0
      %45 = getelementptr inbounds %struct.IDispatch* %42, i32 0, i32 0
      %46 = load %struct.IDispatchVtbl** %45, align 4, !tbaa !0
      %47 = getelementptr inbounds %struct.IDispatchVtbl* %46, i32 0, i32 2
      %48 = load i32 (%struct.IDispatch*)** %47, align 4, !tbaa !0
      %49 = call x86_stdcallcc i32 %48(%struct.IDispatch* %42) nounwind
      br label %50
     
    ; <label>:50                                      ; preds = %0, %44
      %51 = load %struct.IDispatch** %pShell, align 4, !tbaa !0
      %52 = getelementptr inbounds %struct.IDispatch* %51, i32 0, i32 0
      %53 = load %struct.IDispatchVtbl** %52, align 4, !tbaa !0
      %54 = getelementptr inbounds %struct.IDispatchVtbl* %53, i32 0, i32 2
      %55 = load i32 (%struct.IDispatch*)** %54, align 4, !tbaa !0
      %56 = call x86_stdcallcc i32 %55(%struct.IDispatch* %51) nounwind
      call x86_stdcallcc void @CoUninitialize() nounwind
      ret i32 0
    }
     
    declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
     
    declare x86_stdcallcc i32 @CoInitialize(i8*)
     
    declare x86_stdcallcc i32 @CLSIDFromProgID(i16*, %struct._GUID*)
     
    declare x86_stdcallcc i32 @CoCreateInstance(%struct._GUID*, %struct.IUnknown*, i32, %struct._GUID*, i8**)
     
    declare x86_stdcallcc i32 @GetUserDefaultLCID()
     
    declare x86_stdcallcc void @VariantInit(%struct.tagVARIANT*)
     
    declare x86_stdcallcc i16* @SysAllocString(i16*)
     
    declare x86_stdcallcc void @CoUninitialize()
     
    !0 = metadata !{metadata !"any pointer", metadata !1}
    !1 = metadata !{metadata !"omnipotent char", metadata !2}
    !2 = metadata !{metadata !"Simple C/C++ TBAA"}
    !3 = metadata !{metadata !"short", metadata !1}
    !4 = metadata !{metadata !"long", metadata !1}
    !5 = metadata !{metadata !"int", metadata !1}

    上記コードは以下のC言語のソースを clang でアセンブリコード出力(clang -S -O4 hello.c)したものに相当する。

    #include <ole2.h>
     
    int main( int argc, char* argv[] )
    {
        CLSID clsid;
        IDispatch* pShell;
        IDispatch* pFolder;
        DISPID dispid;
        OLECHAR* ptName = L"BrowseForFolder";
        DISPPARAMS param = { NULL, NULL, 0, 0 };
        VARIANT varg[4];
        VARIANT vResult;
     
        CoInitialize( NULL );
     
        CLSIDFromProgID(L"Shell.Application", &clsid );
        CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell);
        pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid );
     
        VariantInit( &varg[0] );
        varg[0].vt = VT_I4;
        varg[0].lVal = 36L;  /* ssfWINDOWS */
     
        VariantInit( &varg[1] );
        varg[1].vt = VT_I4;
        varg[1].lVal = 0L;
     
        VariantInit( &varg[2] );
        varg[2].vt = VT_BSTR;
        varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); 
     
        VariantInit( &varg[3] );
        varg[3].vt = VT_I4;
        varg[3].lVal = 0L;
     
        param.cArgs = 4;
        param.rgvarg = varg;
     
        pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &param, &vResult, NULL, NULL );
     
        VariantInit( &varg[0] );
        VariantInit( &varg[1] );
        VariantInit( &varg[2] );
        VariantInit( &varg[3] );
     
        pFolder = V_DISPATCH( &vResult );
        if ( pFolder != NULL )
        {
            pFolder->lpVtbl->Release( (void*)pFolder );
        }
        pShell->lpVtbl->Release( (void*)pShell );
     
        CoUninitialize();
     
        return 0;
    }

    コンパイル&リンク方法

    C:¥> clang -o hello hello.ll -l ole32  -l oleaut32 -l uuid

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM Wolrd!                      |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+
  7. Hello, COM(Objective-C) World!

    Posted on 3月 16th, 2013 by cx20

    COM(Objective-C)

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は MinGW 版 Objective-C による COM クライアントの例となっている。

    ソースコード

    #import <windows.h>
    #import <ole2.h>
    #import <objc/Object.h>
     
    @interface Hello : Object
    - (void) sayHello;
    @end
     
    @implementation Hello
    - (void) sayHello {
        CLSID clsid;
        IDispatch* pShell;
        IDispatch* pFolder;
        DISPID dispid;
        OLECHAR* ptName = L"BrowseForFolder";
        DISPPARAMS param = { NULL, NULL, 0, 0 };
        VARIANT varg[4];
        VARIANT vResult;
     
        CoInitialize( NULL );
     
        CLSIDFromProgID(L"Shell.Application", &clsid );
        CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell);
        pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid );
     
        VariantInit( &varg[0] );
        varg[0].vt = VT_I4;
        varg[0].lVal = 36L;  /* ssfWINDOWS */
     
        VariantInit( &varg[1] );
        varg[1].vt = VT_I4;
        varg[1].lVal = 0L;
     
        VariantInit( &varg[2] );
        varg[2].vt = VT_BSTR;
        varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); 
     
        VariantInit( &varg[3] );
        varg[3].vt = VT_I4;
        varg[3].lVal = 0L;
     
        param.cArgs = 4;
        param.rgvarg = varg;
     
        pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &param, &vResult, NULL, NULL );
     
        VariantInit( &varg[0] );
        VariantInit( &varg[1] );
        VariantInit( &varg[2] );
        VariantInit( &varg[3] );
     
        pFolder = V_DISPATCH( &vResult );
        if ( pFolder != NULL )
        {
            pFolder->lpVtbl->Release( (void*)pFolder );
        }
        pShell->lpVtbl->Release( (void*)pShell );
     
        CoUninitialize();
    }
    @end
     
    int main(int argc, char *argv[]) {
        id obj = [ Hello alloc ];
        [ obj sayHello ];
     
        return 0;
    }

    実行方法

    C:¥> gcc -o hello hello.m -l objc -l ole32  -l oleaut32 -l uuid

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM(Objective-C) Wolrd!         |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+
  8. Hello, COM(Tcl) World!

    Posted on 3月 15th, 2013 by cx20

    COM(Tcl)

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は Tcl にて TWAPI ならび tcom を用いた COM クライアントの例となっている。

    ソースコード(Tcl + TWAPI)

    package require twapi
    set shell [twapi::comobj "Shell.Application"]
    set folder [$shell BrowseForFolder  0 "Hello, COM(Tcl) World!" 0 36 ]

    ソースコード(Tcl + tcom)

    package require tcom
    set shell [::tcom::ref createobject "Shell.Application"]
    set folder [$shell BrowseForFolder  0 "Hello, COM(Tcl) World!" 0 36 ]

    実行方法

    C:¥> tclsh hello.tcl

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM(Tcl) Wolrd!                 |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+
  9. Hello, Win32 API(GAS) World!

    Posted on 3月 14th, 2013 by cx20

    Win32 API(GAS)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は GAS からの呼出し例である。

    ソースコード(GAS)

            .file   "hello.c"
            .def    ___main;        .scl    2;      .type   32;     .endef
            .section .rdata,"dr"
    LC0:
            .ascii "Hello, World!

    上記コードは、下記の C のソースを MinGW版 GCC にてアセンブリコード出力(gcc -S hello.c)したものである。

    ソースコード(C言語)

    #include <windows.h>
     
    int main( int argc, char* argv[] )
    {
        MessageBox( NULL, "Hello, Win32 API World!", "Hello, World!", MB_OK );
        return 0;
    }

    コンパイル方法(MinGW版 gcc)

    C:¥> gcc -c hello.s
    C:¥> gcc -o hello hello.o

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API World!
    ---------------------------
    OK   
    ---------------------------
  10. Hello, Win32 API(LLVM) World!

    Posted on 3月 13th, 2013 by cx20

    Win32 API(LLVM)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は LLVM Assembler による呼出し例である。

    ソースコード(LLVM)

    ; ModuleID = 'hello.c'
    target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
    target triple = "i686-w64-mingw32"
     
    %struct.HWND__ = type { i32 }
     
    @.str = private unnamed_addr constant [24 x i8] c"Hello, Win32 API World!

    上記コードは、下記の C のソースを clang にてアセンブリコード出力(clang -S -O4 hello.c)したものである。

    ソースコード(C言語)

    #include <windows.h>
     
    int main( int argc, char* argv[] )
    {
        MessageBox( NULL, "Hello, Win32 API World!", "Hello, World!", MB_OK );
        return 0;
    }

    コンパイル方法(MinGW版 clang)

    C:¥> clang -o hello hello.ll

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API World!
    ---------------------------
    OK   
    ---------------------------