Archive for the ‘Win32 API’ Category

  1. Hello, Win32 API(D言語) World!

    Posted on 5月 4th, 2012 by cx20

    Win32 API(D言語)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は D言語 からの呼出し例である。
    D言語では、Platform SDK のヘッダファイル相当のものがプロトタイプ宣言されている為、基本的な Win32 API であれば、C/C++ の場合と同様に、呼び出すことが可能となっている。

    ソースコード

    import std.c.windows.windows;
     
    int main( char[][] args )
    {
        MessageBoxA( null, "Hello, Win32 API(D) World!", "Hello, World!", MB_OK );
        return 0;
    }

    Win32 API のプロトタイプ宣言(参考)

    extern (Windows)
    {
          :
    int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
    int MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
          :
    }

    また、Win32 データ型に関しても、同じ名前の型が、D言語用に定義されている為、特段、言語の差異を意識することなく使うことが可能となっている。

    Win32 データ型 C/C++ データ型 D言語データ型
    HANDLE void * void *
    BYTE unsigned char ubyte
    SHORT short short
    WORD unsigned short ushort
    INT int int
    UINT unsigned int uint
    LONG long int
    BOOL int int
    DWORD unsigned long uint
    ULONG unsigned long uint
    CHAR char char
    WCHAR wchar_t wchar
    LPSTR char * char *
    LPCSTR const char * const(char) *
    LPWSTR wchar_t * wchar *
    LPCWSTR const wchar_t * const(wchar) *
    FLOAT float float
    DOUBLE double double
    LONGLONG __int64 long
    DWORD64 unsigned __int64 ulong

    コンパイル方法(Digital Mars D コンパイラ)

    C:¥> dmd hello.d

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(D) World!
    ---------------------------
    OK   
    ---------------------------
  2. Hello, Win32 API(JNI) World!

    Posted on 5月 3rd, 2012 by cx20

    Win32 API(JNI)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は JNI(Java Native Interface)による呼出し例である。
    Java からは 直接、Win32 API を呼び出すことは出来ないが、JNI 用の DLL を作成することで呼び出すことが可能となっている。

    ソースコード(Java)

    import java.io.*;
     
    public class Hello {
        static {
            System.loadLibrary("Hello");
        }
     
        public native int MessageBox( int hwnd, String text, String title, int type );
     
        public static void main(String args[]) {
            Hello hello = new Hello();
            hello.MessageBox( 0, "Hello, Win32 API(JNI) World!", "Hello, World!", 0 );
        }
    }

    C ヘッダファイル作成

    C:¥> javah -jni Hello

    ソースコード(C ヘッダファイル)

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class Hello */
     
    #ifndef _Included_Hello
    #define _Included_Hello
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     Hello
     * Method:    MessageBox
     * Signature: (ILjava/lang/String;Ljava/lang/String;I)I
     */
    JNIEXPORT jint JNICALL Java_Hello_MessageBox
      (JNIEnv *, jobject, jint, jstring, jstring, jint);
     
    #ifdef __cplusplus
    }
    #endif
    #endif

    ソースコード(C 実装ファイル)

    #include "Hello.h"
    #include <windows.h>
     
    /*
     * Class:     Hello
     * Method:    MessageBox
     * Signature: (ILjava/lang/String;Ljava/lang/String;I)I
     */
    JNIEXPORT jint JNICALL Java_Hello_MessageBox
      (JNIEnv* env, jobject me, jint hwnd, jstring text, jstring caption, jint type)
    {
    #ifdef UNICODE
        const jchar* _text = env->GetStringChars(text, 0); 
        const jchar* _caption = env->GetStringChars(caption, 0); 
        const int result = MessageBoxW(NULL, (LPCWSTR)_text, (LPCWSTR)_caption, type); 
        env->ReleaseStringChars(text, _text); 
        env->ReleaseStringChars(caption, _caption); 
    #else
        /* このコードはマルチバイト文字(MBCS)を考慮していない為、全角文字列を渡した場合に文字化けする。正しくは SJIS に変換する処理が必要。*/
        const char* _text = env->GetStringUTFChars(text, 0); 
        const char* _caption = env->GetStringUTFChars(caption, 0); 
        const int result = MessageBoxA(NULL, (LPCSTR)_text, (LPCSTR)_caption, type); 
        env->ReleaseStringUTFChars(text, _text); 
        env->ReleaseStringUTFChars(caption, _caption); 
    #endif
        return result; 
    }

    Win32 データ型と JNI データ型の対応は主に以下のようになっている。

    Win32 データ型 C/C++ データ型 JNI データ型 Java データ型
    BOOL int jboolean boolean
    BYTE char jbyte byte
    WCHAR wchar_t jchar char
    SHORT short jshort short
    INT int jint int
    LONGLONG __int64 jlong long
    FLOAT float jfloat float
    DOUBLE double jdouble double
    VOID void void void
    LPCSTR const char * jstring string
    LPCWSTR const wchar_t * jstring string

    なお、jstring については、使用時に、正しい C/C++ データ型(ANSI, MBCS / UNICODE)に適宜、変換する必要がある。

    DLL作成(Visual C++)

    C:¥> SET INCLUDE=%JAVA_HOME%include;%JAVA_HOME%includewin32;%INCLUDE%
    C:¥> cl Hello.cpp /LD /link user32.lib

    コンパイル&実行方法

    C:¥> javac Hello.java
    C:¥> java Hello

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(JNI) World!
    ---------------------------
    OK   
    ---------------------------
  3. Hello, Win32 API(JNA) World!

    Posted on 5月 2nd, 2012 by cx20

    Win32 API(JNA)

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

    ソースコード

    import com.sun.jna.Native;
    import com.sun.jna.win32.StdCallLibrary;
     
    public class Hello {
        public interface User32 extends StdCallLibrary {
            User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
            int MessageBoxA(int hwnd, String text, String caption, int type);
        }
     
        public static void main(String[] args) {
            User32 user32 = User32.INSTANCE;
            user32.MessageBoxA(0, "Hello, Win32 API(JNA) World!", "Hello, World!", 0);
        }
    }

    Win32 データ型と JNA データ型の対応は主に以下のようになっている。

    Win32 データ型 C/C++ データ型 Java/JNA データ型
    BYTE char byte
    SHORT short short
    WCHAR wchar_t char
    INT int int
    BOOL int boolean
    LONG long NativeLong(JNA データ型)
    LONGLONG __int64 long
    FLOAT float float
    DOUBLE double double
    LPCSTR const char * String
    LPCWSTR const wchar_t * WString(JNA データ型)
    LPINT int * IntByReference(JNA データ型)
    LPVOID void * Pointer

    コンパイル&実行方法

    C:¥> javac -cp jna.jar;. Hello.java
    C:¥> java -cp jna.jar;. Hello

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(JNA) World!
    ---------------------------
    OK   
    ---------------------------
  4. Hello, Win32 API(UWSC) World!

    Posted on 5月 1st, 2012 by cx20

    Win32 API(UWSC)

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

    ソースコード

    Option Explicit
     
    DEF_DLL MessageBoxA( hwnd, string, string, long ): long: user32.dll
     
    Main()
     
    Procedure Main()
        MessageBoxA( 0, "Hello, Win32 API(UWSC) World!", "Hello, World!", 0 )
    Fend

    Win32 データ型と UWSC データ型(DEF_DLL 構文)の対応は主に以下のようになっている。

    Win32 データ型 C/C++ データ型 UWSC データ型
    INT int int
    LONG long long
    BOOL int bool
    UINT unsigned int uint
    HWND void * hwnd
    LPCSTR const char * string
    LPCWSTR const wchar_t * Wstring
    FLOAT float float
    DOUBLE double double
    WORD unsigned short word
    DWORD unsigned long dword
    BYTE unsigned char byte
    CHAR char char
    PCHAR char * pchar
    WCHAR wchar_t Wchar
    PWCHAR wchar_t * pWchar
    BOOLEAN unsigned char boolean
    LONGLONG __int64 longlong

    実行方法

    C:¥> uwsc hello.uws

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(UWSC) World!
    ---------------------------
    OK   
    ---------------------------
  5. Hello, Win32 API(Lua) World!

    Posted on 4月 30th, 2012 by cx20

    Win32 API(Lua)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Lua にて alien ライブラリを用いた呼出し例である。

    ソースコード

    require "alien"
     
    MessageBox = alien.User32.MessageBoxA
    MessageBox:types{ ret = 'long', abi = 'stdcall', 'long', 'string', 'string', 'long' }
    MessageBox( 0, "Hello, Win32 API(Lua) World!", "Hello, World!", 0 )

    Win32 データ型に対応する Lua の型(alien ライブラリ)としては以下のようなものがある。

    Win32 データ型 C/C++ データ型 Lua
    VOID void void
    INT int int
    UINT unsigned int uint
    DOUBLE double double
    CHAR char char
    LPCSTR const char * string
    LPVOID void * pointer
    PINT int * ref int
    PUINT unsigned int * ref uint
    DOUBLE * double * ref double
    PCHAR char * ref char
    PROC function pointer callback
    SHORT short short
    WORD unsigned short ushort
    BYTE signed char byte
    LONG long long
    DWORD unsigned long ulong
    FLOAT float float

    実行方法

    C:¥> lua hello.lua

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(Lua) World!
    ---------------------------
    OK   
    ---------------------------
  6. Hello, Win32 API(Python) World!

    Posted on 4月 29th, 2012 by cx20

    Win32 API(Python)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Python にて ctypes ライブラリを使用した呼出し例である。

    ソースコード

    import ctypes
     
    user32 = ctypes.windll.user32
    user32.MessageBoxA( 0, "Hello, Win32 API(Python) World!", "Hello, World!", 0 )

    実行方法

    C:¥> python hello.py

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(Python) World!
    ---------------------------
    OK   
    ---------------------------
  7. Hello, Win32 API(PHP) World!

    Posted on 4月 29th, 2012 by cx20

    Win32 API(PHP)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は PHP にて COM ライブラリである DynamicWrapper を経由した Win32 API の呼出し例である。

    なお、PHP 5.4.5 / 5.3.15 より、COM サポートは既定では組み込まれていない為、使用するには、以下の設定を追加する必要がある。

    PHP 設定

    [COM_DOT_NET]
    extension = php_com_dotnet.dll

    ソースコード

    <?php
    $win32 = new COM("DynamicWrapper");
    $win32->Register( "user32.dll", "MessageBoxA", "i=hhsu", "f=s", "r=l" );
    $win32->MessageBoxA( 0, "Hello, Win32 API(PHP) World!", "Hello, World!", 0 );
    ?>

    なお、上記の “i=hhsu” は各引数の型を、”f=s” は呼び出し規約を、”r=l” は戻り値の型を表している。以下は主要なタイプ一覧である。詳細は「An Automation Object for Dynamic DLL Calls | Dr Dobb’s」を参照のこと。

    タイプ 説明
    a オートメーションオブジェクト(IDispatch*)
    c 符号なし文字型(unsigned char)
    d 倍精度浮動小数点数(double)
    f 単精度浮動小数点数(float)
    k COM オブジェクト(IUnknown*)
    h ハンドル(handle)
    l 整数型(long)
    p ポインタ(pointer)
    s 文字列(string)
    t 整数型(short)
    u 符号なし整数型(unsigned int)
    w ワイド文字列(wide string)

    実行方法

    C:¥> php -f hello.php

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(PHP) World!
    ---------------------------
    OK   
    ---------------------------
  8. Hello, Win32 API(Ruby) World!

    Posted on 4月 28th, 2012 by cx20

    Win32 API(Ruby)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Ruby の Win32API ライブラリならびに Ruby/DL2(Ruby 1.9 より標準添付)よる呼出し例である。

    ソースコード(Win32API)

    require 'Win32API'
     
    msgbox = Win32API.new('user32', 'MessageBox', ['i', 'p', 'p', 'i'], 'i')
    msgbox.call( 0, "Hello, Win32 API(Ruby) World!", "Hello, World!", 0 )

    なお、上記の [‘i’, ‘p’, ‘p’, ‘i’], ‘i’ は、各引数と戻り値の型を表している。主なタイプとしては以下の種類がある。詳細は「Ruby 1.9.3 リファレンスマニュアル > ライブラリ一覧 > Win32APIライブラリ > Win32APIクラス」を参照のこと。

    タイプ 説明
    “p” ポインタ型(pointer)
    “l” 数値型(long)
    “i” 整数型(integer)
    “v” void 型

    ソースコード(Ruby/DL2)

    require 'dl/import'
    require 'dl/types'
     
    module User32
      extend DL::Importer
      dlload 'user32'
     
      include DL::Win32Types
      extern 'int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT)'
    end
     
    User32.MessageBoxA( 0, "Hello, Windows API(Ruby) World!", "Hello, World!", 0 )

    Ruby/DL2 では、C言語のプロトタイプ宣言を記述することにより、外部ライブラリの利用が可能となっている。

    実行方法

    C:¥> ruby hello.rb

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(Ruby) World!
    ---------------------------
    OK   
    ---------------------------
  9. Hello, Win32 API(Perl) World!

    Posted on 4月 27th, 2012 by cx20

    Win32 API(Perl)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は Perl にて Win32::API モジュールを用いた呼出し例である。

    ソースコード

    use strict;
    use Win32::API;
     
    my $msgbox= Win32::API->new("user32", "MessageBoxA", "NPPN", "N");
       $msgbox->Call( 0, "Hello, Win32 API(Perl) World!", "Hello, World!", 0 );

    なお、上記の “NPPN”, “N” は各引数と戻り値の型を表している。以下は主要なタイプ一覧である。詳細は「Win32::API – search.cpan.org」を参照のこと。

    タイプ 説明
    I 整数型(int)
    N 数値型(long)
    F 単精度浮動小数点数(float)
    D 倍精度浮動小数点数(double)
    C 文字型(char)
    P ポインタ型(文字列、構造体等へのポインタ)
    S 構造体オブジェクト(Win32::API::Struct)
    K コールバックオブジェクト(Win32::API::Callback)

    コンパイル方法

    C:¥> perl hello.pl

    実行結果

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

    Posted on 4月 26th, 2012 by cx20

    Win32 API(MSIL)

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

    ソースコード

    //  Microsoft (R) .NET Framework IL Disassembler.  Version 4.0.30319.1
    //  Copyright (c) Microsoft Corporation. All rights reserved.
     
    // Metadata version: v2.0.50727
    .module extern user32.dll
    .assembly extern mscorlib
    {
      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .zV.4..
      .ver 2:0:0:0
    }
    .assembly Hello
    {
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                                 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
      .hash algorithm 0x00008004
      .ver 0:0:0:0
    }
    .module Hello.exe
    // MVID: {412A0088-7664-4361-B59D-98DD5760B045}
    .imagebase 0x00400000
    .file alignment 0x00000200
    .stackreserve 0x00100000
    .subsystem 0x0003       // WINDOWS_CUI
    .corflags 0x00000001    //  ILONLY
    // Image base: 0x00360000
     
    // =============== CLASS MEMBERS DECLARATION ===================
    .class private auto ansi beforefieldinit Hello
           extends [mscorlib]System.Object
    {
      .method private hidebysig static pinvokeimpl("user32.dll" winapi) 
              uint32  MessageBox(uint32 hWnd,
                                 string lpText,
                                 string lpTitle,
                                 uint32 uType) cil managed preservesig
      {
      }
      .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint
        // コード サイズ       20 (0x14)
        .maxstack  8
        IL_0000:  nop
        IL_0001:  ldc.i4.0
        IL_0002:  ldstr      "Hello, Windows API(MSIL) World!"
        IL_0007:  ldstr      "Hello, World!"
        IL_000c:  ldc.i4.0
        IL_000d:  call       uint32 Hello::MessageBox(uint32,
                                                      string,
                                                      string,
                                                      uint32)
        IL_0012:  pop
        IL_0013:  ret
      } // end of method Hello::Main
     
      .method public hidebysig specialname rtspecialname 
              instance void  .ctor() cil managed
      {
        // コード サイズ       7 (0x7)
        .maxstack  8
        IL_0000:  ldarg.0
        IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
        IL_0006:  ret
      } // end of method Hello::.ctor
     
    } // end of class Hello

    上記のコードは、以下の C# のプログラムを ildasm.exe で逆アセンブルしたものである。

    ソースコード

    using System.Runtime.InteropServices;
     
    class Hello
    {
         [DllImport("user32.dll")]
         private extern static uint MessageBox(uint hWnd, string lpText, string lpTitle, uint uType);
         static void Main(string[] args)
        {
            MessageBox( 0, "Hello, Win32 API(MSIL) World!", "Hello, World!", 0 );
        }
    }

    コンパイル方法

    C:¥> ilasm Hello.il

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(MSIL) World!
    ---------------------------
    OK   
    ---------------------------