前々回の「VBフォーム(Windows アプリケーション)だって、コマンドプロンプトでDLL?」記事で、"VBフォームからDLLを呼び出す場合、上記エイリアスの手法を .def ファイル内で使用する必要があるらしい"と書きましたが、ちょっと違っていたようです。
マイクロソフトのドキュメントに、
Visual Basic で書かれたプログラムから DLL を呼び出す場合は、ここで示したエイリアスの手法を .def ファイル内で使用する必要があります。エイリアスが Visual Basic プログラムの中で宣言されている場合は、.def ファイル内でのエイリアスは不要です。これは、Visual Basic プログラムでは、Declare ステートメントにエイリアス句を追加することで実現されます。
とあったのですが、VBフォームでエイリアス句の動作確認をしようとして気が付きました。
訂正で、VBフォーム ⇒ CのDLL、VBフォーム ⇒ C++のDLLを呼び出すだけのサンプルを作ってみました。
<注意点>
・DLLでエクスポートしたい関数などは、.def ファイルに記述する必要があります。
・.def ファイルでも、VBフォームでも、エイリアスは一切必要無さそうです。
・DLLファイルが無かったり、呼び出す関数がエクスポートされていない(.def ファイルに記述が無い)と、VB側で例外が発生します。
・お試し結果の出力は、VBフォームの実行ファイル(.exe)をDOS窓でリダイレクト(> や >>)して得ています。
お試し環境
WindowsXP 32bit Edition
Visual C++ & Visual Basic 2008
/*---- VB Form ⇒ C の dll 作成 --------------- コマンドライン -------------*/
D:\vc2008\dllchk>cl /LD testc.c /link /def:testc.def
(testc.dll を作成)
/*----------------------------------------------------------------------------*/
/*---- VB Form ⇒ C++ の dll 作成 ------------- コマンドライン -------------*/
D:\vc2008\dllchk>cl /LD testpp.cpp /link /def:testpp.def
(testpp.dll を作成)
/*----------------------------------------------------------------------------*/
/*---- VB Form ⇒ C の dll 呼出し ------------ お試し結果 ------------------*/
CPRINT01 : String from Visual Basic : Visual Basic01 です。 - 17
CPRINT02 : Values from Visual Basic : 200
VBPRINT01 Return C String : Hi! Visual Basic
VBPRINT02 Called C : Return from C
VBPRINT02 Return C Values : 40000
EXCEPTION DLL 'testc.dll' の 'subc05' というエントリ ポイントが見つかりません。
/*----------------------------------------------------------------------------*/
/*---- VB Form ⇒ C++ の dll 呼出し ------------- お試し結果 ---------------*/
C++PRINT03 : String from Visual Basic : Visual Basic03 です。 - 19
C++PRINT04 : Values from Visual Basic : 300
VBPRINT03 Called C++ : Return from Visual C++
VBPRINT03 Return C++ String : Hello Visual Basic
VBPRINT04 Return C++ Values : 90000
EXCEPTION DLL 'testpp.dll' の 'subpp06' というエントリ ポイントが見つかりません。
/*----------------------------------------------------------------------------*/
/*---- .def 無しで dll 作成 と .dll 無しでの呼出し ----- 結果 --------------*/
EXCEPTION DLL 'testc.dll' の 'subc01' というエントリ ポイントが見つかりません。
EXCEPTION DLL 'testpp.dll' を読み込めません: 指定されたモジュールが見つかりません。(HRESULT からの例外: 0x8007007E)
/*----------------------------------------------------------------------------*/
/*==== VB Form ⇒ C の dll 呼出し ============= お試しソース ===============*/
/*---- testc.def -------------------------------------------------------------*/
LIBRARY testc
EXPORTS
subc01
subc02
/*----------------------------------------------------------------------------*/
/*---- testc.c ---------------------------------------------------------------*/
#include <stdio.h>
#include <string.h> // strcpy_s 関数
void __stdcall subc01(char *s, int d)
{
printf("CPRINT01 : String from Visual Basic : %s - %d\n", s, d);
strcpy_s(s, d, "Hi! Visual Basic");
}
char * __stdcall subc02(int *d)
{
printf("CPRINT02 : Values from Visual Basic : %d\n", *d);
*d *= *d;
return("Return from C");
}
void __stdcall subc05(void)
{
printf("CPRINT05 : Called C ?\n");
}
/*----------------------------------------------------------------------------*/
/*============================================================================*/
/*==== VB Form ⇒ C++ の dll 呼出し ============= お試しソース =============*/
/*---- testpp.def ------------------------------------------------------------*/
LIBRARY testpp
EXPORTS
subpp03
subpp04
/*----------------------------------------------------------------------------*/
/*---- testpp.cpp ------------------------------------------------------------*/
#include <cstdio>
#include <cstring> // strcpy_s 関数
extern "C" char * __stdcall subpp03(char *s, int d)
{
printf("C++PRINT03 : String from Visual Basic : %s - %d\n", s, d);
strcpy_s(s, (unsigned int)d, "Hello Visual Basic");
return("Return from Visual C++");
}
extern "C" void __stdcall subpp04(int *d)
{
printf("C++PRINT04 : Values from Visual Basic : %d\n", *d);
*d *= *d;
}
extern "C" void __stdcall subpp06(void)
{
printf("C++PRINT06 : Called Visual C++ ?\n");
}
/*----------------------------------------------------------------------------*/
/*============================================================================*/
/*==== VB Form ================================ お試しソース ===============*/
/*----------------------------------------------------------------------------*/
Public Class Form1
Private Declare Sub subc01 Lib "testc.dll" (ByVal s As String, ByVal d As Integer)
Private Declare Function subc02 Lib "testc.dll" (ByRef d As Integer) As String
Private Declare Sub subc05 Lib "testc.dll" ()
Private Declare Function subpp03 Lib "testpp.dll" (ByVal s As String, ByVal d As Integer) As String
Private Declare Sub subpp04 Lib "testpp.dll" (ByRef d As Integer)
Private Declare Sub subpp06 Lib "testpp.dll" ()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim a As Integer = 17
Dim d As Integer = 200
Dim s As String = "Visual Basic01 です。"
Try
subc01(s, a)
Console.WriteLine("VBPRINT01 Return C String : " & Strings.Left(s, InStr(s, Chr(0)) - 1))
Console.WriteLine("VBPRINT02 Called C : " & subc02(d))
Console.WriteLine("VBPRINT02 Return C Values : " & d)
subc05()
Catch ex As EntryPointNotFoundException
Console.WriteLine("EXCEPTION " & Err.Description)
Catch ex As DllNotFoundException
Console.WriteLine("EXCEPTION " & Err.Description)
Catch ex As Exception
Console.WriteLine("EXCEPTION その他の例外が発生しました。")
End Try
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim a As Integer = 19
Dim d As Integer = 300
Dim s As String = "Visual Basic03 です。"
Try
Console.WriteLine("VBPRINT03 Called C++ : " & subpp03(s, a))
Console.WriteLine("VBPRINT03 Return C++ String : " & s)
subpp04(d)
Console.WriteLine("VBPRINT04 Return C++ Values : " & d)
subpp06()
Catch ex As EntryPointNotFoundException
Console.WriteLine("EXCEPTION " & Err.Description)
Catch ex As DllNotFoundException
Console.WriteLine("EXCEPTION " & Err.Description)
Catch ex As Exception
Console.WriteLine("EXCEPTION その他の例外が発生しました。")
End Try
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*============================================================================*/