Windows Dev. Site

Java Native Interface : C++/CLI

.NETフレームワークのC++/CLIの柔軟性を示す例として、一つの文字列を4つの方法でコンソール出力をしてみた。

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <jni.h>
#include <iostream>

using namespace System;

void JavaPrint(char*);

int main(array<System::String ^> ^args)
{
	char str[100];

	sprintf(str, "Hello World\n");

	// .Net
	String^ s = gcnew String(str);
	Console::Write(s);

	// Win
	HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	WriteConsole(hStdout, (CONST VOID *)str, (DWORD)strlen(str), NULL, NULL);

	// Std C
	printf("%s", str);

	// Java
	JavaPrint(str);

	std::cout << "Hit any key ..." << std::endl;
	getchar();
    return 0;
}

void JavaPrint(char *str)
{
	JNIEnv* env;
    JavaVM* jvm;
	JavaVMOption options[3];
	JavaVMInitArgs vm_args;

    options[0].optionString = "-Xmx128m";
    options[1].optionString = "-verbose:gc";
    options[2].optionString = "-Djava.class.path=C:/temp";

    vm_args.version = JNI_VERSION_1_6;
    vm_args.options = options;
    vm_args.nOptions = 3;

	JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
	
    jclass clazz = env->FindClass("JPrint");
	jmethodID mid = env->GetStaticMethodID(clazz, "SystemPrint", "(Ljava/lang/String;)V");
	env->CallStaticVoidMethod(clazz, mid, env->NewStringUTF(str));

    jvm->DestroyJavaVM();
}

これを実行すると以下のようになります。

Console4

Javaのコードはコンパイルして、C:\tempにclassファイルを配置しておきます。

public class JPrint{
	public static void SystemPrint(String arg){
		System.out.print(arg);
	}
}

なんか面白い。自己満足!(ネタ的にはちょっと古いけど、残しておきたかったので)
重要なのは、.NETにもJavaにも同時にアクセスできてしまうということです。
(こういうの過去資産の活用に使えるんですよね。)

最近C++/CXというものもでてきましたが、ネイティブとも.NETとも違うまた新しいスタイル(WinRT)の開発をすることができます。C++/CLIも陳腐化してしまうのかなぁ。
また勉強しないと・・