SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

C++で作ったアプリケーションとJScriptの連携

C++からJScriptの実行とその逆の実行

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード ソースコード (9.5 KB)

C++で作ったネイティブアプリケーションからJScriptで書かれたスクリプトを実行する方法を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 WindowsにはWindows Scriptと呼ばれるスクリプトを実行するインフラが用意されており、VBScriptとJScriptという2つのスクリプト言語が搭載されています。

 本稿ではC++で書かれたネイティブアプリケーションからJScriptを実行し、JScriptからC++のクラスメソッドを呼び出す方法や、反対にC++からJScriptの関数を実行する方法を紹介します。また、JScriptのArrayオブジェクトをC++で作成する方法についても紹介します。

対象読者

 以下のアプリケーションを開発したことがある人。

  • C++、JScriptを使ったアプリケーション
  • Win32 APIを使ったアプリケーション
  • COMコンポーネントを利用したアプリケーション

作成/実行環境

  • Windows XP/Vista
  • Visual Studio 2005

ソースコード

 ダウンロードしたアーカイブには、プロジェクトが2つ収録されています。内容を表1に示します。

表1.収録内容
プロジェクト名 内容
call_jscript JScriptからC++のクラスメソッドを呼び出す。
jscript_array C++上でArrayオブジェクトを生成し、JScriptの関数を呼び出す。
注意
 内容をシンプルにするためにエラー対策や例外捕捉のコードは省略しています。実際にアプリケーションを作られる際には注意してください。

JScriptを使うための準備

必要なヘッダーファイルとライブラリのリンク

 必要なヘッダーファイルとライブラリをリンクするために、次のように「stdafx.h」を書き換えます。

stdafx.h
#pragma once
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"comsupp.lib")
#pragma comment(lib,"ole32.lib")
#include <tchar.h>
#include <windows.h>
#include <objbase.h>
#include <comutil.h>
#include <dispex.h>
#include <activscp.h>
#include "../ImplIUnknown.h" // 後述

COMの初期化と解放

 Windows ScriptはCOMベースで実装されているので、COMの初期化と解放を実装します。

COMの初期化と解放
// (解放を簡単にするためのマクロを定義しておく)
#define SAFE_RELEASE(p) {if(p){(p)->Release();(p)=NULL;}}

int _tmain(int argc, _TCHAR* argv[]) {
  CoInitialize(NULL);
  //TODO : COM を使ったコードを書く
  CoUninitialize();
  return 0;
}

IUnknownの実装

 JScriptを実行したり、JScriptから呼び出せるメソッドを実装したりするために、独自のCOMクラスを実装することになります。すべてのCOMクラスはIUnknownインターフェースを実装しています。IUnknownを容易に実装するためのマクロIMPL_IUNKNOWNを「ImplIUnknown.h」に定義します。

ImplIunknown.h
#pragma once
// インスタンスを作成
#define CO_CREATE(X,Y) X *Y=new X;
// インスタンスを解放
#define SAFE_RELEASE(p) if((p)) { (p)->Release(); (p)=NULL; }

// IUnknown インターフェイスの実装
// クラスのコンストラクタで refCount(1) として初期化すること。
#define IMPL_IUNKNOWN(IF_NAME) \
public:\
  STDMETHODIMP_(ULONG) AddRef() {\
    return ++refCount;\
  }\
  STDMETHODIMP_(ULONG) Release() {\
    --refCount;\
    if (refCount <= 0) {\
      delete this;\
      return 0;\
    }\
    return refCount;\
  }\
  STDMETHODIMP QueryInterface(const IID & riid,void **ppvObj) {\
    if (!ppvObj)\
      return E_POINTER;\
    if (IsEqualIID(riid, __uuidof(IF_NAME)) ||\
      IsEqualIID(riid, IID_IUnknown)) {\
      AddRef();\
      *ppvObj=this;\
      return S_OK;\
    }\
    return E_NOINTERFACE;\
  }\
private:\
  ULONG refCount;

 IMPL_IUNKNOWNマクロは引数が1つあります。これには例えばIDispatchのようなインターフェースの型を指定します。QueryInterfaceにて指定したインターフェースの問い合わせがあると、thisポインタを返し、戻り値はS_OKとなります。そうでない場合はE_NOINTERFACEを返します。

 インターフェースの型からインターフェースID(IID)への変換には__uuidofを使っています。

次のページ
JScriptからC++のクラスメソッドを呼び出す 1

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

syu5()

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1827 2008/08/20 10:39

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング