クラス内にて 引数に void* 型を持つ関数の override ができません


投稿ツリー



前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 .3 .4 | 投稿日時 2011/7/3 1:03
びぎな・D 
DMD 2.053

void*型を引数に取る関数を、継承したクラスからoverrideしたいと思い、以下のようなコードをコンパイルしようとした所、

module a;
class A
{
    int something(int m, void* n)
    {
        return 0;
    }
}
module b;
class B : A
{
    override int something(int m, void* n) // Error!
    {
        return 1;
    }
}
import b;
void main()
{
    B c = new B;
    c.something(3, cast(void*)0);
}

以下のようなエラーが発生しました。
Error: function b.B.something does not override any function

そもそも、何がしたかったのかというと、
class MyForm : Form
{
    extern (Windows)
    override int WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        return 0;
    }
}

このような記述方法を取りたかったわけなのですが、一番目の例のように、引数を最後に移動しただけでは解決できませんでした。

解決策や、回避策等ご存じでしたら教えて頂きたいです。

よろしくお願い致します。
投票数:25 平均点:3.60
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/7/3 2:00
びぎな・D 
自己レスで申し訳ないのですが、
どうやら同じ型の指定があるライブラリを別々にインポートしてしまったのが原因?のようでした。

module a;
import std.c.windows.windows;
module b;
import win32.winbase;

これを、win32.winbase に統一してみたところ、すんなりとコンパイルが通ってしまいました。

どちらも、最終的にはvoid*型だったようなのですが…。

お騒がせ致しました。
投票数:23 平均点:3.91
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/7/3 3:54
SHOO  管理人   投稿数: 658
一応…

extern(Windows)な関数は基本的にオーバーライドできない気が。
COMオブジェクトだったらできたかも?

あと、ウィンドウプロシージャみたいなコールバック関数は
メンバ関数ではダメなので、サブクラス化など工夫が必要です。
ご注意を。
投票数:32 平均点:2.19
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 | 投稿日時 2011/7/3 3:57
びぎな・D 
多少話がずれてしまいますが、再度質問を。

WNDPROCをクラス内のメンバ関数に設定する事はできますでしょうか?

import win32.winbase, win32.winuser;
class Window
{
    extern(Windows)
    int WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }
}

簡単に、
lpfnWndProc = cast(WNDPROC)&window.WndProc;
等と打っても、アクセス違反の例外が発生して、ウィンドウが表示されません。

何だか茨の道を突き進んでいるような感覚です…
投票数:25 平均点:3.60
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/7/3 12:18
KU6  新米   投稿数: 5
Dに限った話ではないですが、メンバ関数を設定する事は出来ません。

メンバ関数は内部的にthisポインタを関数の引数に取るはずなので、
要求されている関数の型に合わなくなってしまいます。

解決方法としてはstaticを付けることです。

もちろん通常のメンバ変数などへアクセス出来なくなってしまうため、
アクセスしたい場合は一工夫必要です。
投票数:27 平均点:5.93
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/7/3 23:14
SHOO  管理人   投稿数: 658
それをするための方法の一つが、サブクラス化です。

軽くネットで漁って見たところ、ちょうどD言語の情報が出てきました。
ご紹介いたします。
http://d.hatena.ne.jp/utautai/20100214
投票数:29 平均点:6.90
返信する
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2011/8/3 11:58
びぎな・D 
class 内にてWndProcのような関数を持つ場合には

HWND hWnd;
extern(Windows) static LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}

のような形にしておいて、
thisポインタを

・SetProp / GetProp にて取得する
・CreateWindowEx の最後の引数に this を指定し、WM_NCCREATE 時に LPARAM より LPCREATESTRUCT を取得し、CREATESTRUCTのメンバである lpCreateParams に設定された this を取得する

このような方法で取得し、クラス内にて hWnd を設定した後に、HandleMessage を呼び出す。

このようにすることで、目的を達成できましたので、こちらにご報告させていただきます。

皆さん、有用な情報を教えて頂き、ありがとうございます。
投票数:67 平均点:3.88
返信する

このトピックに投稿する

題名
ゲスト名
投稿本文

  条件検索へ


メインメニュー

ログイン

ユーザー名:


パスワード:





パスワード紛失  |新規登録

Menu