- PR -

VS.NET2005でのDLL作成と呼び出し方法

1
投稿者投稿内容
黒鯛
会議室デビュー日: 2005/11/12
投稿数: 8
投稿日時: 2006-09-08 08:49
こんにちは。
掲記の件で、アドバイス頂ければ幸いです。
Microsoft Visual Studio 2005でのDLL作成方法と使用方法についてご教示ください。
1.DLL作成
(1) Visual C++を起動し、[ファイル]-[新規作成]-[プロジェクト]を選択します。
(2) プロジェクトの種類:MFC,テンプレート:MFC DLL を選択します。
(3) プロジェクト名:testdll01
(4) アプリケーションの設定で、MFC拡張DLLを選択します。
(5) [完了]ボタン押下で、スケルトンを作成します。
(6) [ファイル]-[新規作成]-[ファイル]を選択します。
(7) Visual C++のヘッダーファイル(.h)を選択します。
(8) 下記のコードを記述し、TestMsgBox.hというファイル名で保存します。
#ifndef __TESTMSGBOX__
#define __TESTMSGBOX__

int WINAPI Dll_TestMessageBox();

#endif
(9) [ファイル]-[新規作成]-[ファイル]を選択します。
(10) Visual C++のC++ファイル(.cpp)を選択します。
(11) 下記のコードを記述し、TestMsgBox.cppというファイル名で保存します。
#include "StdAfx.h"
#include "TestMsgBox.h"

int WINAPI Dll_TestMessageBox()
{
return AfxMessageBox((LPCTSTR)"このメッセージボックスはDLL内の関数から呼び出されています");
れています");
}
(12) testdll01.defを開き、EXPORTSの欄に作成した関数名を記述します。
; testdll01.def : DLL のモジュール パラメータを宣言します。

LIBRARY "testdll01"

EXPORTS
; 明示的なエクスポートはここへ記述できます
Dll_TestMessageBox @1
(13) testdll01をビルドします。

2.作成したDLLを呼び出す
(1) Visual C++を起動し、[ファイル]-[新規作成]-[プロジェクト]を選択します。
(2) プロジェクトの種類:MFC,テンプレート:MFCアプリケーション を選択します。
(3) プロジェクト名:testexe01
(4) アプリケーションの種類で、ダイアログベースを選択します。
(5) [完了]ボタン押下で、スケルトンを作成します。
(6) リソースビューのDialogで、IDD_TESTEXE01_DIALOGを開き、ボタンを貼り付けます。
(7) ボタンのIDはIDC_BUTTON1になっています。
(8) 新規追加したボタンに対し、イベントハンドラの追加で、BN_CLICKEDメッセージの関数ハンドラ(OnBnClickedButton1)を追加編集します。
(9) 以下のようにコードを追加します。
#include "TestMsgBox.h"
(省略)
void Ctestexe01Dlg::OnBnClickedButton1()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
Dll_TestMessageBox();
}
(10) testdll01プロジェクトのTestMsgBox.hをtestexe01プロジェクトへコピーします。
(11) testdll01\\\\\\\\debug\\\\\\\\testdll01.libをtestexe01\\\\\\\\testexe01\\\\\\\\debugへコピーします。
現状ではビルドすると、以下のエラーメッセージが表示されてしまいます。
どのように対応すれば良いでしょうか?

------ ビルド開始: プロジェクト: testexe01, 構成: Debug Win32 ------
リンクしています...
testexe01Dlg.obj : error LNK2019: 未解決の外部シンボル "int __stdcall Dll_TestMessageBox(void)" (?Dll_TestMessageBox@@YGHXZ) が関数 "public: void __thiscall Ctestexe01Dlg::OnBnClickedButton1(void)" (?OnBnClickedButton1@Ctestexe01Dlg@@QAEXXZ) で参照されました。
C:\\\\\\\\source\\\\\\\\testexe01\\\\\\\\Debug\\\\\\\\testexe01.exe : fatal error LNK1120: 外部参照 1 が未解決です。
ビルドログは "file://c:\\\\\\\\source\\\\\\\\testexe01\\\\\\\\testexe01\\\\\\\\Debug\\\\\\\\BuildLog.htm" に保存されました。
testexe01 - エラー 2、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2006-09-08 09:02
DLLを呼び出すほうでは、Libファイルをリンクさせていないのですか?
プロジェクトのプロパティでリンカ→入力あたりでLibファイルを指定するか、
#pragma comment( lib, "〜〜〜.lib" )
をどこかに入れるかして、リンクしないとダメです。

ちなみに
引用:

コード:
AfxMessageBox((LPCTSTR)"このメッセージボックスはDLL内の関数から呼び出されています"); 




はなんで、LPCTSTRにキャストしているのでしょうか?
もしかして、キャストしなかったらエラーが出たからでしょうか?
AfxMessageBoxはTCHARを意識しますので、_T マクロを使って作ってください。
コード:
AfxMessageBox( _T( "このメッセージボックスはDLL内の関数から呼び出されています" ) ); 


VC2005からは、デフォルトの文字セットが、「マルチバイト文字セット」から「Unicode文字セット」に変更されています。
ですので、プロパティをいじっていない場合、TCHARはすべてwchar_t型としてコンパイルします。
(LPCTSTRはconst wchar_t*になる。)
ですので、

(LPCTSTR)"このメッセージボックスはDLL内の関数から呼び出されています"



( const wchar_t* )"このメッセージボックスはDLL内の関数から呼び出されています"

となり、Unicode文字列でないものをUnicodeに無理やりキャストすることになります。
(CP932(Shift_JIS)とUnicodeは対応していないし、1バイト文字2文字で1文字を作ることになる→つまりメチャクチャ)
黒鯛
会議室デビュー日: 2005/11/12
投稿数: 8
投稿日時: 2006-09-08 15:02
Blueさん、こんにちは。
早々のアドバイスをありがとうございます。
さて、うまく行きました。
まず、プロジェクトのプロパティの[リンカ]-[入力]-[追加の依存ファイル]でDLLを指定しました。この設定箇所が不明だったのです。
昔のVSだと、[リンク]タブの[オブジェクト/ライブラリ モジュール]で指定すればOKだったと思います。このあたりバージョンが変わると使い勝手が変わるので悩ましいところです。次に、LPCTSTRでキャストしてる理由ですが、ご指摘の通りコンパイルエラーが出てしまったので、とりあえずキャストすればいいかな?ということでやったらそのまま通ったので深く考えていませんでした。お恥ずかしい限りです。実行したら文字化けしていました(笑)
1

スキルアップ/キャリアアップ(JOB@IT)