トップ回答者
DLL内に作ったクラスのメンバ関数の利用方法を教えてください。

質問
-
どうも、こんにちわ。
VC++の初心者です。
質問したい内容は、件名に記した通りです。
環境は、
WinXP
VS 2005 ver.8
VC++
です。
Win32コンソールアプリケーション/DLLを選択。
プロジェクト名は、MyDll としました。■MyDll.hに
追加するクラスを宣言しました。//追加コード
class MyClass1{
char sDat1[80];
public:
MyClass1(char *s1);
MyClass1();
~MyClass1();
void SetAdd(int a, int b, int *c);
};■MyDll.cpp
追加クラスの実装//追加コード
MyClass1::MyClass1(char *s1)
{
lstrcpy(sDat1, s1);
MessageBox(NULL, sDat1, "MyClass1のコンストラクタ", MB_OK);
}
MyClass1::MyClass1()
{
sDat1[0] = '\0';
MessageBox(NULL, sDat1, "MyClass1のコンストラクタ", MB_OK);
}
MyClass1::~MyClass1()
{
MessageBox(NULL, sDat1, "MyClass1のデストラクタ", MB_OK);
}
void MyClass1:etAdd(int a, int b, int *c)
{
*c = a + b;
}☆上の文字化けしたメンバ関数の名前は、SetAdd()です。
これでビルドをしまして、
MyDll.dll と MyDll.lib の生成に成功しました。■次にWin32コンソールアプリケーション/Windowsアプリケーションを選択。
プロジェクト名は、UseDll としました。■UseDll.cppのコード一部
// UseDll.cpp : アプリケーションのエントリ ポイントを定義します。
//#include "stdafx.h"
#include "UseDll.h" //☆★☆追加コード
#include "MyDll.h" //☆★☆追加コード
#pragma comment(lib, "MyDll.lib") //☆★☆追加コード__declspec(dllimport) void SetAdd(int, int, int *); //☆★☆追加コード
///////////////////////////////////////////////////
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);// TODO: ここにコードを挿入してください。
//☆★☆記述箇所はここからです。MyClass1 ob1;
int suu1 = 0;
ob1.SetAdd(100, 200, &suu1);return 0;
//☆★☆記述箇所は、ここまで。
MSG msg;
HACCEL hAccelTable;上記のように追加して、DLLにあるメンバ関数を
活用しようとしているのですが、うまく行かない次第です。クラスのメンバ関数宣言がエラー箇所でして、
UseDll.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall MyClass1::~MyClass1(void)" (??1MyClass1@@QAE@XZ) が関数 _wWinMain@16 で参照されました。
UseDll.obj : error LNK2019: 未解決の外部シンボル "public: void __thiscall MyClass1:etAdd(int,int,int *)" (?SetAdd@MyClass1@@QAEXHHPAH@Z) が関数 _wWinMain@16 で参照されました。
UseDll.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall MyClass1::MyClass1(void)" (??0MyClass1@@QAE@XZ) が関数 _wWinMain@16 で参照されました。
\UseDll\Debug\UseDll.exe : fatal error LNK1120: 外部参照 3 が未解決です。が出力されます。
DLLの関数呼び出し方法は、わかったのですが、
クラスのメンバ関数呼び出しとなると、その方法を模索中の状態です。ご教授のほど、よろしくお願いします。
回答
-
クラスの場合、クラスごとエクスポートする必要があります。
SetAddはMyClass1のメンバ関数(メソッド)ですので、
>__declspec(dllimport) void SetAdd(int, int, int *); //☆★☆追加コード
はまったくもって意味を持ちません。
→不要
MSDN
http://msdn2.microsoft.com/ja-jp/library/a90k134d(VS.80).aspx
関数のときと同様、__declspecをclassキーワードの直後に指定します。
コード書くのは面倒ですので、Googleとかで、「クラス __declspec DLL」等をキーワードに
検索してみてください。
すべての返信
-
クラスの場合、クラスごとエクスポートする必要があります。
SetAddはMyClass1のメンバ関数(メソッド)ですので、
>__declspec(dllimport) void SetAdd(int, int, int *); //☆★☆追加コード
はまったくもって意味を持ちません。
→不要
MSDN
http://msdn2.microsoft.com/ja-jp/library/a90k134d(VS.80).aspx
関数のときと同様、__declspecをclassキーワードの直後に指定します。
コード書くのは面倒ですので、Googleとかで、「クラス __declspec DLL」等をキーワードに
検索してみてください。 -
早速のご回答、ありがとうございます。
ご教授くださった内容を試してみたのですが、なかなかうまく行きません。
■MyDll.hで、
class __declspec(dllexport) MyClass1{
とコードを修正しました。
ビルドは成功しました。
■次にUseDll.cppの方で、
__declspec(dllimport) MyClass1{
public:
MyClass1(char *s1);
MyClass1();
~MyClass1();
void SetAdd(int a, int b, int *c);
};とコードを修正しました。
ビルドすると、
usedll.cpp(13) : warning C4091: '__declspec(dllimport)' : 変数が何も宣言されていないときは、'MyClass1' の左辺を無視します。
usedll.cpp(13) : error C2143: 構文エラー : ';' が '{' の前にありません。
usedll.cpp(13) : error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?)と3つのエラーが出ます。
■MainDllの所で、オブジェクト宣言をして、メンバ関数を呼んでいます。
MyClass1 obj1;
int suu1 = 0;obj1.SetAdd(100,200, &suu1);
この状態で、あれこれと模索しています。
問題解決の方法、ご教授のほど、よろしくお願いします。
-
>__declspec(dllimport) MyClass1{
classが頭に抜けているけど。
というか、DLLの関数やクラスを使いたい場合、一般的にはDLL側で作成したヘッダファイルを
インクルードして使えるように記述すするのですが、参考にされている本にはそこらへんを
触れていないでしょうか?
http://msdn2.microsoft.com/ja-jp/library/8fskxacy(VS.80).aspx
のコードを使わせてもらうと
MyDll.hでは
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
class CLASS_DECLSPEC MyClass1{
// 省略
として、MyDll.cppでは
#define _EXPORTING
#include "MyDll.h"
// 省略
として、DLLを作成します。
そして、DLLを使う側では、
#include "MyDll.h"
#pragma comment(lib, "MyDll.lib") // コンパイルオプションでも指定可
// 省略
とします。