サンプルプログラムをWindowsアプリケーションで・・・

9/30に作ったJavaアプリケーション呼び出しのサンプルプログラムが結局コンソールアプリケーションだったので、それをWindowsアプリケーションで作り直してみました。


コンソールアプリケーションと違ってWindowsアプリケーションは実行時のパラメータを一つの文字列として受け渡しを行うだけでなく、実行プログラム名はパラメータに設定されないので、GetCommandLine()関数でパラメータを再取得しています。
また、このGetCommandLine()関数でもパラメータは一つの文字列として受取るので、JvmEnvクラスに新たにloadArg(LPTSTR arg, bool first_program)を追加しました。
JvmEnv.cpp(追加メソッド)

/*
 *  プログラム起動時のパラメータを保存する
 *  param   : パラメータ(LPTSTR)
 *
 *  return  : 無し
 */
void JvmEnv::loadArgs(LPTSTR arg, bool first_program) {
    String org = String(arg);
    size_t fpos = 0, epos = String::npos;
    size_t argn = 0;
    String token;
    do {
        fpos = org.find_first_not_of(_T(" "), fpos);
        if (fpos != String::npos) {
            if (org.substr(fpos, 1) == String(_T("\""))) {
                fpos++;
                epos = org.find_first_of(_T("\""), fpos);
            }
            else {
                epos = org.find_first_of(_T(" "), fpos);
            }
            if (epos != String::npos) {
                token = org.substr(fpos, epos-fpos);
                epos++;
            }
            else {
                token = org.substr(fpos);
            }
            fpos = epos;
        }
        if (token.length() > 0) {
            if (first_program && (argn == 0))
                caller_name = token;
            else {
                if ((token.substr(0,1) == String(_T("-"))) && (token.substr(1,1) != String(_T("-")))) {
                    java_params.push_back(token);
                }
                else {
                    prog_params.push_back(token);
                }
            }
            argn++;
        }
    } while (fpos != String::npos);
}

次にサンプルのプルグラムで、
wjnicall.h

#ifndef _WIN_JNICALL
#define _WIN_JNICALL

#include <windows.h>
#include <tchar.h>

#include <sstream>

#include <jvmenv.h>
#include <jvmservice.h>

#endif  //  _WIN_JNICALL

wjnicall.cpp

#include "wjnicall.h"


int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR     lpCmdLine,
                     int       nCmdShow) {
    std::basic_stringstream<_TCHAR> out;

    LPTSTR cmdLine = GetCommandLine();

    AllocConsole();

    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    JvmEnv env;
    env.loadArgs(cmdLine);
    env.addJavaParam(String(_T("-Xms8m")));
    env.addJavaParam(String(_T("-Xms16m")));
    env.addJavaParam(String(_T("-server")));
    env.addJavaParam(String(_T("-Djava.compiler=NONE")));
    String latest = env.findJvm(JRERuntimeLib+LatestVersion, false);

    if (env.loadJLib(latest) == 0) {
        env.addClassPath(_T("E:\\Workspace\\Common\\Java\\JNI\\net\\classes"));
        if (env.createJvm() == 0) {
            JvmService service = JvmService(env);
            service.setCallClass("IfInfoTest", "net.test");
            service.execute();
            service.end_wait();
            service.setReturnCodeName("return_code");
            service.result();
            out << _T("Execute result ") << service.getReturnCode() << _T(":") << service.getReturnMessage() << std::endl;
            WriteConsole(hStdout, out.str().c_str(), (DWORD)out.str().length(), NULL, NULL);
            MessageBox(NULL, service.getReturnMessage().c_str(), _T("Result"), MB_OK);
            env.destroyJvm();
        }
        env.unloadJLib();
    }

    FreeConsole();

    return 0;
}

このサンプルプログラムでは、Javaのアプリケーションでコンソール(System.out)に出力される結果を表示させるために、Windowsアプリケーションにはあるまじき行為かもしれませんが、AllocConsole()関数であえてコンソールを表示させています。