バイナリリソースから読み込んだクラスデータの関数が実行されません

解決


brAin  URL  2003-11-27 22:57:58  No: 52658  IP: [192.*.*.*]

このようなクラスがあります。
class CBase{
(変数省略)
public:
    virtual void Function() = 0;
}

class CChild : public CBase{
(変数省略)
public:
    void Function();
}

class CParent{
public:
    CChild  *p;
(その他変数省略)
    void Func2();
}

void CParent::Func2()
{
    // forループ(i)
    p[i].Function();
}

あらかじめWin32ConsoleAplliでクラス[CChild]の配列データを組んで、バイナリで出力したファイルをリソースとして組み込み
Win32Aplliで
  FindResource > LoadResource > LockResource
で先頭ポインタを、[CParent]の[CChild]型ポインタ[p]で受け取り、その[CChild]配列データを[CParent]内で扱うのですが
[p]における[CChild][CBase]の変数はちゃんとデータも入っていて機能するのですが
void CParent::Func2() 内の p[i].Function();
が、デバッグで確かめたところNULLになっていて触れると強制終了してしまいます。
Func2のほかでも、[p]における関数は全てNULLになっており機能しません。
ConsoleAplli側でデバッグしたところ、関数にはNULLじゃない数値が格納されていました。

こういった関数の実行はムリなのでしょうか。
それとも実行の仕方がまずいのでしょうか。
どうかご助力お願いいたします <(_  _*)>

編集 削除
YuO  2003-11-28 02:21:13  No: 52659  IP: [192.*.*.*]

VC++の実装の場合,CBaseは仮想関数を含みますから,
CBaseは「仮想関数テーブルへのポインタ」という暗黙のメンバを持っています。
#大抵のC++実装はそうなっているはず。

CChild::Functionは仮想関数ですから,
p[i].Function()の解決は仮想関数テーブルを経由します。
当然,予期した場所に仮想関数テーブルがなければ未定義動作でしょうね。


というわけで,方法を一から変更する必要がありそうです。

まず,CChildは内部のデータを入出力できるようにして,それをリソースに蓄えます。
そして,そのデータを読み込んでCChildの配列を生成することで,
CParentを復元する,というのが安全な方法です。

編集 削除
brAin  URL  2003-12-05 01:45:01  No: 52660  IP: [192.*.*.*]

読み込んだデータ量によって、ポインタ[p]にnewでメモリ確保し
そこにリソースデータをコピーすることで解決いたしました。
YuOさん、ありがとうございます。

編集 削除