0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C++Advent Calendar 2022

Day 8

C++(EXE)からDLLの関数を呼び出す構成についてDLLの言語をVB6から.NET Frameworkへ移行する手順

Last updated at Posted at 2022-07-08

1. 概要

  • C++(EXE)からDLLの関数を呼び出す構成について、DLLの言語をVB6からNETFx 4.7.2 (Visual Basic) に移行する際の手順
  • 必要なエラー処理等は記載されていないことがあります

2. 変更前のプログラム

  • 抜粋のみ記載
  • 作成したVB6のDLLはc:\sample\Sample.dllに配置
  • C++はMFCを利用しているが、MFCを使わない場合も同様と想定される

本例はC++側の実装に問題(VB6側と型の不一致)があり、C++のcheckDataの引数は本来CStringが望ましい。よって、MFCを使わない場合と同様とは言えない。

2.1. VB6

CHK.cls
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "CHK"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True

Public Function CheckData(ByVal param1 As String) As Boolean
	<処理は省略。param1に応じてTrue、またはFalseを返却する>
End Function

2.2. レジストリへの登録

  • 管理者権限が必要
  • 解除は必須ではないが、インタフェース変更時には必要
; 解除
regsvr32.exe c:\sample\Sample.dll /u

; 登録
regsvr32.exe c:\sample\Sample.dll

2.3. C++

  • importコマンドでビルド時にActiveX DLLからの情報を組み込む
#import "C:\sample\Sample.dll"
using namespace Sample;

int checkData(int param1)
{
	int iResult = 0;

	//COM初期化
	::CoInitialize(NULL);

	// インターフェースの取得
	_CHKPtr pCheck(__uuidof(CHK));

	// BSTRに変換
	BSTR	bParam1 = param1.AllocSysString();

	// 関数呼び出し
	iResult = pCheck->CheckData(bParam1);

	// 開放
	SysFreeString(bParam1);
	pCheck->Release();

	// COMの終了処理
	::CoUninitialize();

	// 値を返却
	if (iResult == 0 )	{
		//false
		return 0;
	} else {
		//true
		return 1;
	}
}

3. 変更後のプログラム

  • 抜粋のみ記載
  • 作成した.NETのDLLはc:\sample\Sample.dllに配置
  • C++はMFCを利用しているが、MFCを使わない場合も同様と想定される

本例はC++側の実装に問題(.NET側と型の不一致)があり、C++のcheckDataの引数は本来CStringが望ましい。よって、MFCを使わない場合と同様とは言えない。

3.1. .NET (NETFx 4.7.2)

  • 検証した.NET のバージョンは、.NET Framework 4.7.2(NETFx 4.7.2)
  • 公開メソッドに対するインタフェースを作成し、作成したインタフェースに属性<ComVisible(True)>の付加が必要
  • 公開メソッドの属性の説明
    • インタフェースの実装となるため、作成したインタフェースをImplementsで指定する
    • <ClassInterface(ClassInterfaceType.None)>を追加
    • ProgId(Visual Basic 2008 Express変換で自動付加)はC++側からの呼び出しでは使用しないが、WSHからの呼び出しでは必要
  • プロジェクトのプロパティで次を設定
    項目 設定値
    アセンブリ情報の「アセンブリをCOM参照可」 チェック ON
    アセンブリ情報の「ビルドタブのCOM相互運用機能」 チェック OFF
    今回の例ではCI(自動ビルド)を行っているためこの設定となる。チェックをONとすると管理者権限が必要となりCIが実施できない。COM相互運用のためのアセンブリ登録(RegAsm.exe利用)は、後述の手順で別途実施
CHK.vb
<ComVisible(True)>
Public Interface ICHK
	Function CheckData(ByVal param1 As String) As Boolean
End Interface

<ClassInterface(ClassInterfaceType.None)>
<ProgId("CHK_NET.CHK")>
Public Class CHK
	Implements ICHK

    Public Function CheckData(ByVal param1 As String) As Boolean Implements ICHK.CheckData
        <処理は省略。param1に応じてTrue、またはFalseを返却する>
    End Function
End Class

3.2. レジストリへの登録

  • 管理者権限が必要
  • 解除は必須ではないが、インタフェース変更時には必要
  • /codebaseグローバル アセンブリ キャッシュにインストールしない場合に利用する
  • /tlbによりタイプ ライブラリ(アセンブリ内で定義されたアクセス可能な型の定義)が生成される。このファイルをC++でimportする
  • 登録でアセンブリのレジストリ登録が行われSample.tlbが生成される
SET BIN=C:\Windows\Microsoft.NET\Framework\v4.0.30319

; 解除
%BIN%\RegAsm.exe /tlb c:\sample\Sample.dll /unregister

; 登録
%BIN%\RegAsm.exe c:\sample\Sample.dll /codebase /tlb

実施結果

C:\WINDOWS\system32>C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe C:\sample\sample.dll /unregister
Microsoft .NET Framework Assembly Registration Utility 4.8.4084.0
for Microsoft .NET Framework Version 4.8.4084.0
Copyright (C) Microsoft Corporation.  All rights reserved.

型は正常に登録が解除されました。

C:\WINDOWS\system32>C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe c:\sample\sample.dll /codebase
Microsoft .NET Framework Assembly Registration Utility 4.8.4084.0
for Microsoft .NET Framework Version 4.8.4084.0
Copyright (C) Microsoft Corporation.  All rights reserved.

RegAsm : warning RA0000 : 署名されていないアセンブリを /codebase を使用して登録すると、同じコンピューターにインストール されるその他のアプリケーションとの競合が生じる可能性があります。/codebase スイッチは署名されたアセンブリのみに使用できます。アセンブリに厳密な名前を付けて、再登録してください。
型は正常に登録されました。

3.3. C++

  • importコマンドでビルド時にタイプライブラリからの情報を組み込む
    • import対象がタイプライブラリ(.tlb)に変更
  • インターフェースの取得時のインタフェース名がVB6 ActiveX DLLの場合から変更となる
#import "C:\sample\Sample.tlb"
using namespace Sample;

int checkData(int param1)
{
	int iResult = 0;

	//COM初期化
	::CoInitialize(NULL);

	// インターフェースの取得
	ICHKPtr pCheck(__uuidof(CHK));

	// BSTRに変換
	BSTR	bParam1 = param1.AllocSysString();

	// 関数呼び出し
	iResult = pCheck->CheckData(bParam1);

	// 開放
	SysFreeString(bParam1);
	pCheck->Release();

	// COMの終了処理
	::CoUninitialize();

	// 値を返却
	if (iResult == 0 )	{
		//false
		return 0;
	} else {
		//true
		return 1;
	}
}

参考情報

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?