classのDLLに動的リンクするとき、直接newキーワードを使うにはどうしたらいいでしょうか

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
黒崎圭一

classのDLLに動的リンクするとき、直接newキーワードを使うにはどうしたらいいでしょうか

#1

投稿記事 by 黒崎圭一 » 4年前

「classのDLLに動的リンクするとき、直接newキーワードを使うにはどうしたらいいでしょうか」

少し前からDLLの作成について学ばせていただいています。

静的リンクでは特に問題を感じられませんでしたが、
やっかいなのは動的リンクでした。

先日やっとclassのDLL化と動的リンクまで間接的ながら成功したのですが
どうも違うような気がしてなりません。

CMyClassというクラスを作成して、(もちろんメソッドはvirtualで)
以下のような全域関数をexportしました。

コード:

extern "C" declspec(dllexport) void __stdcall CreateInstance(void)
{
  return new CMyClass;
}
そして呼び出す側では関数ポインターを定義して
以下のようにクラスにアクセスすることができました。

コード:

typedef void (*PFUNC)(void);
HMODULE hModule = LoadLibrary("MyClass.dll");
PFUNC pFuncCreateInstance = (PFUNC)GetProcAddress(hModule, "CreateInstance");

CMyClass* pClass = pFuncCreateInstance();
/* クラスの使用 */
delete pClass;
しかし、オープライブラリのOpenCVなどで動的リンクを試してみたところ、
以下のように直接的にアクセスすることができました。

コード:

cv::Mat* pMat = new cv::Mat;
CreateInstance()を使った私の方法は何か間違ってるような気がします。
正しい方法がありましたら是非教えて頂きたいたいです。

アバター
lriki
記事: 88
登録日時: 9年前

Re: classのDLLに動的リンクするとき、直接newキーワードを使うにはどうしたらいいでしょうか

#2

投稿記事 by lriki » 4年前

new が使えないとは具体的にどういう状況ですか?(シンボル未定義でリンクエラーが出ている?)
普通はクラス自体をエクスポートすることで使えるようになるはずです。
https://msdn.microsoft.com/ja-jp/library/a90k134d.aspx

あと、CreateInstance()を使う方法自体は間違いではありません。
COMのように互換性の向上や実装の隠蔽のために使うこともあります。
ただ、2つ目のコードのようにDLLの中でnewしたオブジェクトをexe側でdeleteするのは厳禁です。
特にexeとdllを別のコンパイラでビルドした場合など、new と delete の実装がペアになっていないと問題になります。
CreateInstance()を使う場合はペアとなるDeleteInstance()のような関数を用意し、DLLの中で delete キーワードで削除するのが無難です。

閉鎖

“C言語何でも質問掲示板” へ戻る