可変調引数を持つ関数のラッピングの方法

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

可変調引数を持つ関数のラッピングの方法

#1

投稿記事 by 焼肉 » 2年前

GoogleのC++のコーディング規約に則ってDXライブラリの関数のラッピングをしています。
といっても大文字で始まる関数の頭文字を小文字に直すだけなのですが、関数の引数が可変調の場合のやり方で詰まってしまいました。

ラッピングを行いたいのはDXライブラリのGraphFilter関数とGraphFilterBlt関数でソースを見た所以下のようになっていました。

コード:

extern DXLIBAPI int GraphFilter(int GrHandle, int FilterType /* DX_GRAPH_FILTER_GAUSS 等 */ , ... ) ; // 画像にフィルター処理を行う
同じような質問が既に上がっていたので見てみたのですが、失敗してしまいました。
StackOverFlow


以下のやり方だとエラーになってしまいます。

コード:

template <typename ... Args>
int graphFilter(int graph_handle, int filter_type, Args const & ... args) {
	return GraphFilter(graph_handle, filter_type, args ...);
}
エラー内容
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int const&, int const&)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int, int, int, int>(int, int, int const&, int const&, int const&, int const&, int const&)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int, int, int, int>(int, int, int const&, int const&, int const&, int const&, int const&)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int const&, int const&)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int const&, int const&)

これはどのように書けば可変調の引数を持つ関数をラッピング出来るでしょうか?

焼肉

Re: 可変調引数を持つ関数のラッピングの方法

#2

投稿記事 by 焼肉 » 2年前

ソースが書いていませんので、追記します。
引数は全てint型です。

コード:

graphFilter(fill_screen, Filter::kGauss, 16, fill_gauss_rate_ );
graphFilter(fill_screen, Filter::kTwoColor, 20, Color::kBlack, 0, Color::kWhite, 255);
graphFilter(edge_screen, Filter::kTwoColor, 20,  Color::kBlack, 0, Color::kWhite, 255);
graphFilter(fill_screen, Filter::kGauss, 16, fill_finish_gauss_rate_ );
graphFilter(edge_screen, Filter::kGauss, 16, edge_finish_gauss_rate_ );

焼肉

Re: 可変調引数を持つ関数のラッピングの方法

#3

投稿記事 by 焼肉 » 2年前

追記します。
const &
が問題なのかと確認してみた所これも失敗してしまいました。

コード:

// 画像・スクリーンにフィルターをかける
template <typename ... Args>
int graphFilter(int graph_handle, int filter_type, Args ... args) {
	return GraphFilter(graph_handle, filter_type, args ...);
エラー

コード:

wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int, int)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int, int, int, int>(int, int, int, int, int, int, int)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int, int, int, int>(int, int, int, int, int, int, int)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int, int)
wasm-ld: error: build/LiquidEffect.o: undefined symbol: int graphFilter<int, int>(int, int, int, int)

焼肉(解決済み)

Re: 可変調引数を持つ関数のラッピングの方法

#4

投稿記事 by 焼肉(解決済み) » 2年前

出来ました。
お騒がせしました。

コード:

/**
 * @brief スクリーン・画像にフィルターを施す
 * 
 * @param graphHandle 
 * @param FilterType 
 * @param ... 
 * @return int 
 */
int graphFilter(int graph_handle, int filter_type, ...) {
	va_list va;
	va_start(va, filter_type);
	int returnNum = GraphFilter(graph_handle, filter_type, va);
	va_end(va);
	return returnNum;
}

焼肉

Re: 可変調引数を持つ関数のラッピングの方法

#5

投稿記事 by 焼肉 » 2年前

すいません、出来ませんでした。
コンパイルは通るのですが、意図した結果にならず、元の関数と違った挙動になる様です。

参照魚
記事: 109
登録日時: 6年前

Re: 可変調引数を持つ関数のラッピングの方法

#6

投稿記事 by 参照魚 » 2年前

filter_typeごとに具体な引数を取得して、それを明示的にGraphFilteに渡すことになるかと思います。

コード:

va_list va;
va_start(va, filter_type);
switch ( filter_type ) {
case DX_GRAPH_FILTER_MONO: //モノトーンフィルタ
	{
		int Cb = va_args( va, int );
		int Cr = va_args( va, int );
		GraphFilter( graph_handle, filter_type,Cb,Cr );
	}
	break;
}
va_end( va );

焼肉(解決済み)

Re: 可変調引数を持つ関数のラッピングの方法

#7

投稿記事 by 焼肉(解決済み) » 2年前

>>>参照魚

ありがとうございます。
おかげで出来ました。

コード:

// スクリーン・画像にフィルターを施す
int graphFilter(int graph_handle, int filter_type, ...) {
	int return_num = kSuccessCode;
	va_list va;
	va_start(va, filter_type);
	switch(filter_type) {
		case GraphEffect::kGauss:
		{
			int pixel_width = va_arg( va, int );
			int prm = va_arg( va, int );
			return_num = GraphFilter(graph_handle, filter_type, pixel_width, prm);
		}
		break;
		case GraphEffect::kTwoColor:
		{
			int threshold = va_arg( va, int );
			int low_color = va_arg( va, int );
			int low_alpha = va_arg( va, int );
			int high_color = va_arg( va, int );
			int high_alpha = va_arg( va, int );
			return_num = GraphFilter(graph_handle, filter_type, threshold, low_color, low_alpha, high_color, high_alpha);
		}
		break;
		default:
		break;
	}
	va_end(va);
	return return_num;
}

焼肉(解決済み)

Re: 可変調引数を持つ関数のラッピングの方法

#8

投稿記事 by 焼肉(解決済み) » 2年前

自分で貼り付けたコードを3行目のみソース修正しました。
ありがとうございました。

X int return_num = kSuccessCode;
○ int return_num = kErrorCode;

コード:

// スクリーン・画像にフィルターを施す
int graphFilter(int graph_handle, int filter_type, ...) {
	int return_num = kErrorCode;
	va_list va;
	va_start(va, filter_type);
	switch(filter_type) {
		case GraphEffect::kGauss:
		{
			int pixel_width = va_arg( va, int );
			int prm = va_arg( va, int );
			return_num = GraphFilter(graph_handle, filter_type, pixel_width, prm);
		}
		break;
		case GraphEffect::kTwoColor:
		{
			int threshold = va_arg( va, int );
			int low_color = va_arg( va, int );
			int low_alpha = va_arg( va, int );
			int high_color = va_arg( va, int );
			int high_alpha = va_arg( va, int );
			return_num = GraphFilter(graph_handle, filter_type, threshold, low_color, low_alpha, high_color, high_alpha);
		}
		break;
		default:
		break;
	}
	va_end(va);
	return return_num;
}

返信

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