- PR -

メソッドの引数にコールバック先を指定する方法

1
投稿者投稿内容
未記入
会議室デビュー日: 2006/11/22
投稿数: 3
投稿日時: 2006-11-22 23:39
Javaで、あるメソッドに対して、コールバックさせたいメソッドを引数として指定することはできるのでしょうか。
もしできる場合、その方法を教えて頂けませんでしょうか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-11-23 00:14
引用:

未記入さんの書き込み (2006-11-22 23:39) より:

Javaで、あるメソッドに対して、コールバックさせたいメソッドを引数として指定することはできるのでしょうか。
もしできる場合、その方法を教えて頂けませんでしょうか。


「Java コールバック関数」 で検索しましょう。
コールバックではなく、単に動的にメソッドを呼び出したいのであれば、
「Java リフレクション」 で検索しましょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
sabro
会議室デビュー日: 2006/10/19
投稿数: 17
投稿日時: 2006-11-23 14:52
Java SE 7で関数ポインタの導入が予定されています。つまり、まだ現在ではそのような機能はないんだと思います。

単純にコールバックを実現させたいだけであれば、Observerパターンが使えるので調べてみてください。
_________________
sabro
ヒマをみつけてWeb開発
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-23 15:32
Javaだと呼び出したいメソッドを持ったinterfaceを作成し、
そのinterfaceの実装を引数に渡すのが一般的ですね。
ようするにObserverパターンになるのですが。

どうせ関数ポインタにせよ引数はきまっていないとまともに呼べないわけですから
interfaceで型を明確化したほうが大抵の場合は便利です。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-11-24 09:46
分かりやすくやすさと再利用性からすると、
java.lang.Runnableのインスタンスを渡すのがいいかも。

runnable.run()

でコールバックということで。
未記入
会議室デビュー日: 2006/11/22
投稿数: 3
投稿日時: 2006-11-24 09:55
回答して下さった方々、ありがとうございます。
質問の仕方が悪くて申し訳ありません。
実は、C言語で書かれたライブラリに

typedef int (*XXX_T)(char *str, int x, char *str2)

int aaa(int a, XXX_T func); /*funcはコールバック関数*/

という関数aaa()があって、これをJavaから使いたいのです。
JavaからC言語のライブラリを使用するためにはJNIを使う
というのはわかるのですが、
javahでヘッダファイルを作るためのクラスファイルを作成するために

public class hoge {
private native int aaa(int a, ここが不明);
}

のような感じで書けないものなのでしょうか。

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-24 11:58
引用:

未記入さんの書き込み (2006-11-24 09:55) より:
実は、C言語で書かれたライブラリに

typedef int (*XXX_T)(char *str, int x, char *str2)

int aaa(int a, XXX_T func); /*funcはコールバック関数*/

という関数aaa()があって、これをJavaから使いたいのです。
JavaからC言語のライブラリを使用するためにはJNIを使う
というのはわかるのですが、
javahでヘッダファイルを作るためのクラスファイルを作成するために

public class hoge {
private native int aaa(int a, ここが不明);
}

のような感じで書けないものなのでしょうか。



おなじ回答を繰り返しますが、interfaceを作ってメソッドを定義して
そのinterfaceを引数として渡します。
JNIを使おうがそのあたりは変わりませんよ。

コード:
/** コールバック用インターフェース */
public interface Callback {
    /** コールバック関数 */
    int callback(String arg1, int arg2, String arg3);
}

public class hoge {
    private native int aaa(int a, Callback callbackObject);
}


あとはJNI内部からcallbackObject.callback()を呼んでやる、と。

蛇足かもしれませんがC言語の関数の戻り値がintになっている場合、
エラーコードを返す作りになっていることが多いので実際にはJava側のメソッドは
適切に例外を投げるようにして戻り値はvoidにしてしまうのがよいですね。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2006-11-24 12:45
こんにちは。
引用:

未記入さんの書き込み (2006-11-24 09:55) より:

実は、C言語で書かれたライブラリに

typedef int (*XXX_T)(char *str, int x, char *str2)

int aaa(int a, XXX_T func); /*funcはコールバック関数*/

という関数aaa()があって、これをJavaから使いたいのです。
JavaからC言語のライブラリを使用するためにはJNIを使う
というのはわかるのですが、
javahでヘッダファイルを作るためのクラスファイルを作成するために

public class hoge {
private native int aaa(int a, ここが不明);
}

のような感じで書けないものなのでしょうか。



もしかしてですが、
C言語のint aaa(int a, XXX_T func);という関数を
直接JNIでコールできると思っていますか?

実際JNIの実装経験があればわかると思いますが、
関数のシグネチャも引数も変わってしまいますよ。

あと、コールバック関数が呼び出されるタイミング(同一スレッドから?別スレッドから?)
を考慮しないと、実装がかわってくると思います。
1

スキルアップ/キャリアアップ(JOB@IT)