Visual C++ 6.0(ATL2.0)のActiveX DLLをDelphiから呼び出す


DelphiからVisual C++のルーチンを利用するには、そのルーチンをActiveX DLLのラッパーに包んで利用するのが楽な方法です。ActiveX DLLにはタイプライブラリが含まれているので、そのDLLをシステムに登録(普通Regsvr32を使う)すると「タイプライブラリの取り込み」でDelphiに簡単にタイプライブラリを取り込むことができます。タイプライブラリを取り込んだActiveX DLLは、Delphiのユニットのように扱うことができます。

ステップ1 「プロジェクト/タイプライブラリの取り込み」で目的のActiveX DLLをDelphiのIDEにインストールする。

ステップ2 「インストール」ダイアログが開いたら「OK」ボタンを押す。

 

ステップ3 このようにタイプライブラリが取り込まれVCLのラッパーが作られる(つまり、Delphiのユニットとして使えるようになる)

ここまで来れば、ActiveX DLLもただのユニットなので、ふつうのクラスのように扱うことができます。

 

サンプル(Delphi)

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  AXMUTEXLib_TLB, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    FMutex: TMutex;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
	Locked: WordBool;
begin
    FMutex := TMutex.Create(Self);
    Locked := FMutex.LockMutex('MyMutex1');
    if Locked then
        Label1.Caption := 'すでに起動されています。'
    else
        Label1.Caption := '起動しました。';
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
	FMutex.Unlock;
end;

end.

サンプル(VC++)

/*****************************************************************************

     AxMutex.dll: Mutex Object
      Mutex.cpp : CMutex のインプリメンテーション

     Copyright (C)2000 by Nakamura,T. All rights reserved.

 *****************************************************************************/
#include "stdafx.h"
#include "AxMutex.h"
#include "Mutex.h"

/////////////////////////////////////////////////////////////////////////////
// CMutex


//
//  オブジェクトが破棄されるとき
//  =============================
HRESULT CMutex::FinalRelease()
{
	if (((ULONG)m_hMutex == 0) || ((ULONG)m_hMutex == ERROR_ALREADY_EXISTS))
		return S_OK;

	if (m_locked)
	{
		ReleaseMutex(m_hMutex);
		CloseHandle(m_hMutex);
	}

	return S_OK;
}

//
//  ロックされているかどうかを返す
//  ==============================
STDMETHODIMP CMutex::IsLocked(VARIANT_BOOL *locked)
{
	*locked = _variant_t(m_locked);
	return S_OK;
}

//
//  待機関数の待ち時間
//  ===================
STDMETHODIMP CMutex::get_MiliSeconds(long *pVal)
{
	*pVal = m_miliSeconds;
	return S_OK;
}

STDMETHODIMP CMutex::put_MiliSeconds(long newVal)
{
	m_miliSeconds = newVal;
	return S_OK;
}

//
//  アンロックする
//  ==============
STDMETHODIMP CMutex::UnlockMutex()
{
	if (m_locked)
	{
		ReleaseMutex(m_hMutex);
		CloseHandle(m_hMutex);
		m_locked = false;
	}
	return S_OK;
}


STDMETHODIMP CMutex::Unlock()
{
	return UnlockMutex();
}

//
//  ロックする
//  ==========
STDMETHODIMP CMutex::LockMutex(BSTR mutexName, VARIANT_BOOL *result)
{
	USES_CONVERSION;
	LPTSTR pMutex = OLE2A(mutexName);
	
	// MUTEXオブジェクトを作成
	m_hMutex = CreateMutex(NULL, TRUE, pMutex);

	*result = _variant_t(false);
	m_locked = false;
	
	// オブジェクトが作成できたか
	if (m_hMutex == 0)
		*result = _variant_t(true);	// 失敗
	else if ((ULONG)m_hMutex == ERROR_ALREADY_EXISTS)
		*result = _variant_t(true);	// すでに存在した。
	else
	{
		// ロックを試みる
		if (WaitForSingleObject(m_hMutex, m_miliSeconds) != WAIT_OBJECT_0)
			*result = _variant_t(true);   // 失敗
		else
			m_locked = true;   // 成功
	}


	return S_OK;
}

サンプル(IDL)

// AxMutex.idl : AxMutex.dll 用の IDL ソース ファイル
//

// このファイルはタイプ ライブラリ (AxMutex.tlb) を作成するために
// タイプ ライブラリ作成ツール MIDL によって処理されます。

import "oaidl.idl";
import "ocidl.idl";
	[
		object,
		uuid(AF4C44E0-B723-47A9-B134-7B967675E502),
		dual,
		helpstring("IMutex Interface"),
		pointer_default(unique)
	]
	interface IMutex : IDispatch
	{
		[id(2), helpstring("メソッド UnlockMutex")] HRESULT UnlockMutex();
		[id(3), helpstring("メソッド IsLocked")] HRESULT IsLocked([out, retval]VARIANT_BOOL *locked);
		[propget, id(4), helpstring("プロパティ MiliSeconds")] HRESULT MiliSeconds([out, retval] long *pVal);
		[propput, id(4), helpstring("プロパティ MiliSeconds")] HRESULT MiliSeconds([in] long newVal);
		[id(6), helpstring("メソッド Unlock")] HRESULT Unlock();
		[id(7), helpstring("メソッド LockMutex")] HRESULT LockMutex([in]BSTR mutexName, [out, retval]VARIANT_BOOL* result);
	};

[
	uuid(D6B0038D-DAF1-40F9-B27F-E52ADDBA8FC8),
	version(1.0),
	helpstring("AxMutex 1.0 タイプ ライブラリ")
]
library AXMUTEXLib
{
	importlib("stdole32.tlb");
	importlib("stdole2.tlb");

	[
		uuid(B0F297CE-2411-436F-B7D7-05D606145B6E),
		helpstring("Mutex Class")
	]
	coclass Mutex
	{
		[default] interface IMutex;
	};
};