重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

DLL作成の機会がいろいろ調べているのですが、教えていただきたいことがあります。
1.インポートライブラリについて
 Windowsで暗黙的リンクでDLLをリンクする場合、
 インポートライブラリを利用するようですが、
 これは、DLL内のポインタと関数名を紐付けるような
 役割だと想定しています。
 仮に関数等ヘッダーで公開されている部分以外で
 DLLを更新した場合、インポートライブラリも
 再リンクするような場面があるのでしょうか。
 特に再リンクしなくてもDLLの更新が反映されたので・・
2.DLLのクラスの継承について
 DLL内に作成したクラスを継承することは不可能ですかね。
 DLLが更新された場合、インスタンスのイメージが違うため
 newやdeleteの処理で当初リンクしたインスタンスのイメージで
 行いますよね。

A 回答 (4件)

>>"DLLのデーター"は”アプリのデーター領域”に配置される


>>という認識は間違いですか?

>間違いですね。(あっさり)

間違いですか。
では、"DLLのデータ"はどこに配置されるのでしょう?
呼びだし側に"DLL専用”の領域が新規にできるのですか?

できたら論拠となるMSDNのページを示して頂きたいです。
(日本語が良いですが、機械翻訳でわかりずらいページも多いです。
でしたら、英語でも構いません。)

>継承クラスをインスタンス化したときに
>領域が取られるわけですが、DLLのインスタンス部分の
>サイズはDLLによって定義されるのではないか

具体的に考えましょう
class Base
{
int m_BaseMember1;
};

なるクラスがDLLからエクスポートされているとします。
clas Ext : publc Base
{
int m_ExtMember1;
}
という風にアプリで派生させ、Extのオブジェクトを作成したとします。
int = 32ビット前提で考えますと
Baseオブジェクトの大きさは4バイト
Extオブジェクトの大きさは8バイトです。
(Base部分4バイト、Ext独自部分4バイト)

今Baseを修正し, int m_BaseMember2を追加したとします。
つまり
class Base
{
int m_BaseMember1;
int m_BaseMember2;
};

となったとします。
Extには変更なしとします。

新たなExtのサイズは12バイトです。
(Base部分8バイト、Ext独自部分4バイト)

このように基本クラスのインスタンスが
派生クラスのインスタンス中に完全に取り込まれるのは
DLLだろうと普通のアプリだろうと同様です。

DLLの場合は、
(基本クラスを取り込まずに)
ポインタでつなぐので
基本クラスのサイズが増えても
派生クラスのサイズは影響を受けない

などとはなっていません。
    • good
    • 0
この回答へのお礼

返答が遅くなり申し訳ないです。
>このように基本クラスのインスタンスが
>派生クラスのインスタンス中に完全に取り込まれるのは
>DLLだろうと普通のアプリだろうと同様です。
ではやはり、基本クラスの更新に伴って、派生クラスのコンパイルが必要に
なってくるのですね。
ありがとうございます。

お礼日時:2009/05/26 15:31

>アプリで定義した継承クラスを new した場合、


>DLLで定義した基底クラスのインスタンスはDLLのデーター領域にでき、
>アプリで定義した継承クラスの部分はアプリのデーター領域にできる・・?

あのーーー
"DLLのデーター領域"と”アプリのデーター領域”の違いがよくわかりません。
説明をお願いします。

http://msdn.microsoft.com/ja-jp/library/h90dkhs0 …
によりますと

”Win32 DLL は、呼び出し側プロセスのアドレス空間に割り当てられます。
既定では、DLL を使用するプロセスごとに、
すべての DLL のグローバル変数および
静的変数のインスタンスが作成されます。”

素直によむと
DLLのデータは呼び出し側プロセス(アプリのことですね)
のデータ領域に配置される
ように解釈できます。

ですから、私には
"DLLのデーター領域"と”アプリのデーター領域”の違いがわかりません。
"DLLのデーター"は”アプリのデーター領域”に配置される
という認識は間違いですか?
    • good
    • 0
この回答へのお礼

間違いですね。(あっさり)
というより表現が適切ではなかったと思っています。
アプリが起動したときにDLLを読み込み
継承クラスをインスタンス化したときに
領域が取られるわけですが、DLLのインスタンス部分の
サイズはDLLによって定義されるのではないかと考えている
ということです。

お礼日時:2009/05/24 09:47

DLLについてはこちらで詳細に解説されています。


http://msdn.microsoft.com/ja-jp/library/7h0a8139 …

MSDNにはWindows上での開発に関わる情報がたくさんあります。
わからないことがあったら、MSDNで調べてみましょう。

DLLですが、一般のアプリと変わりません。

あえて注意する点といいますと
常駐オブジェクトの扱いですね。

C++では良く"資源管理はコンストラクタ"と言われます。
コンストラクタ中でメモリを確保し、
デストラクタで廃棄するのがお決まりパターンとなっています。

しかし、この方法はDLL内のstaticオブジェクトには向かないようです。
(staticでなく、アプリが自分で構築する分には問題ない)
コンストラクタとは別の初期化関数を用意し、
アプリから明示的に呼ぶ方法が無難なようです。

特に、オブジェクトがスレッドを抱え込んでいて、
オブジェクトの生成と同時にスレッドも起動したい場合、
DLL内常駐オブジェクトでは絶対と言っていいほどできません。

各種常駐オブジェクトの初期化関数呼び出しを一個の関数に
まとめて"ライブラリ初期化関数"としてエクスポートし、

”DLLを使う際には、最初に初期化関数を呼んでね"

というお約束にしとく手をよく使います

(後始末も同様です)
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
勉強になります。
> DLLですが、一般のアプリと変わりません。
アプリで定義した継承クラスを new した場合、
DLLで定義した基底クラスのインスタンスはDLLのデーター領域にでき、
アプリで定義した継承クラスの部分はアプリのデーター領域にできる・・?

お礼日時:2009/05/24 08:40

>仮に関数等ヘッダーで公開されている部分以外で


> DLLを更新した場合、インポートライブラリも
> 再リンクするような場面があるのでしょうか。

再リンクの必要はありません。

>DLL内に作成したクラスを継承することは不可能ですかね。
可能です。
実際、MFCユーザーはよくやっていることですよね。
MFCを"ダイナミック・リンク"して、
MFC内のCViewやCDialogから
アプリ側で派生クラスをこしらえるのは、
ごく普通にできていることです。

ただし、前提条件があります。
更新前と更新後で同一の処理系を使うことです。

C++は関数の多重定義を解決するため、
関数名に変更を加えます。
その変更方法は、
完全に(処理系の)デベロッパに委ねられており、
統一が図られていません。

A社の処理系で作成したDLLを利用して
アプリを作り
B社の処理系でビルドすることはできません。

DLLも含めて、全体を
B社の処理系で
リビルドすれば問題はなくなります
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

> 再リンクの必要はありません。
やはりそうなのですか。
バイナリエディタで開くと関数名しかないので
関数の定義をしているだけなのですね。

> 実際、MFCユーザーはよくやっていることですよね。
> MFCを"ダイナミック・リンク"して、
> MFC内のCViewやCDialogから
> アプリ側で派生クラスをこしらえるのは、
> ごく普通にできていることです。
そういえば・・
よろしければやり方をご教示いただけるとありがたいです。
気になるのはインスタンスの生成と開放の部分なのですが、
その他処理系の問題以外に注意しなければならないところなどあれば
お願いいたします。

お礼日時:2009/05/23 19:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!