Data Effectorの条件式からcall関数で呼び出す、ユーザー定義関数の作成例を示します。
ユーザー定義関数の仕様
入力文字列中の半角英字を大文字に変換します。
以下に、ユーザー定義関数の作成例を示します。
#if defined( WIN32 ) #define DEFUNC_QUALIFIER __declspec(dllexport) #else #define DEFUNC_QUALIFIER #endif #if defined(__cplusplus) extern "C" DEFUNC_QUALIFIER int Defunc( int, void **, void ** ); #endif #include <stdlib.h> #include <string.h> #include <malloc.h> #include <ctype.h> #include "libAsis.h" /* ユーザー定義関数の仕様 * ・引数として、ASCII文字だけから構成される文字列を受け取る * ・その文字列に含まれる小文字を大文字に変換した文字列を返す */ /* エラーコード */ enum { C_UFNC_NORMAL_END = 0, C_UFNC_ERR_UNKNOWN_CALLCODE, C_UFNC_ERR_INSUFFICIENT_MEMORY, C_UFNC_ERR_NULL_HANDLE, C_UFNC_ERR_NULL_DATA, C_UFNC_ERR_TOO_FEW_OR_TOO_MANY_ARGUMENTS, C_UFNC_ERR_INVALID_ARGUMENT, C_UFNC_ERR_NULL_RETURN_DATA }; /* ハンドル */ struct userhandle_tag { int sz_buffer; /* 作業領域のサイズ */ char *buffer; /* 作業領域 */ }; /* 呼び出しコード別の処理 */ /* 環境開設 */ struct userhandle_tag* defunc_open( void ); /* 環境閉鎖 */ void defunc_close( struct userhandle_tag* ); /* 変換実行 */ int defunc_exec( struct userhandle_tag*, int, char **, char ** ); /* 領域解放 */ void defunc_free( struct userhandle_tag*, char * ); /* ユーザー定義関数の実装 */ DEFUNC_QUALIFIER int Defunc( int Oper, /* 呼び出し種別 */ void **Handle, /* ハンドル */ void **Data /* 引数, および返却用の領域 */ ) { struct userhandle_tag *handle = NULL; int ret = C_UFNC_NORMAL_END; switch( Oper ) { case DE_USER_FUNCTION_THREAD_OPEN: /* 環境の開設 */ handle = defunc_open( ); if( handle == NULL ) { /* 失敗 */ ret = C_UFNC_ERR_INSUFFICIENT_MEMORY; } else { /* ハンドルを返却 */ *Handle = handle; } break; case DE_USER_FUNCTION_THREAD_CLOSE: /* 環境の閉鎖 */ handle = (struct userhandle_tag*)*Handle; defunc_close( handle ); break; case DE_USER_FUNCTION_EXEC: /* 変換の実行 */ if( *Handle == NULL ) { return C_UFNC_ERR_NULL_HANDLE; } if( *Data == NULL ) { return C_UFNC_ERR_NULL_DATA; } handle = (struct userhandle_tag *)*Handle; { int num_arg; /* 引数の数 */ int offset; char **arg_list; /* 引数のリスト */ char *result; /* 結果が格納された領域のポインタ */ /* 引数の情報の分解 */ memcpy(&num_arg, (char*)(Data[0]), sizeof(int)); memcpy(&offset, (char*)(Data[0]) + sizeof(int), sizeof(int)); arg_list = (char**)((char*)(Data[0]) + + sizeof(int)*2 + offset); /* 変換処理の実施 */ ret = defunc_exec(handle, num_arg, arg_list, &result ); if( ret != C_UFNC_NORMAL_END ) { return ret; } else { /* 変換結果の設定 */ Data[0] = result; } } break; case DE_USER_FUNCTION_FREE: /* 領域の解放*/ handle = (struct userhandle_tag *)*Handle; { char *result; /* 結果が格納された領域のポインタ */ result = (char*)Data[0]; defunc_free( handle, result ); } break; default: return C_UFNC_ERR_UNKNOWN_CALLCODE; } return C_UFNC_NORMAL_END; } /* 環境開設処理 */ struct userhandle_tag * defunc_open( void ) { struct userhandle_tag *wk_handle; /* ハンドルの獲得 */ wk_handle = (struct userhandle_tag *) calloc(1, sizeof(struct userhandle_tag )); if( wk_handle == NULL ) { return NULL; } /* 作業領域の獲得 */ wk_handle->sz_buffer = 1024; wk_handle->buffer = (char*)malloc( wk_handle->sz_buffer ); if( wk_handle->buffer == NULL ) { free( wk_handle ); return NULL; } /* 獲得したハンドルを返す */ return wk_handle; } /* 環境閉鎖処理 */ void defunc_close( struct userhandle_tag *handle ) { if( handle != NULL ) { if( handle->buffer != NULL ) { free( handle->buffer ); handle->buffer = NULL; } free( handle ); handle = NULL; } return ; } /* 変換実行 */ int defunc_exec( struct userhandle_tag *handle, int num_arg, char **arg_list, char **result ) { /* 入力文字列のポインタ */ const char *instr; /* 入力文字列の長さ */ int len_instr; /* 出力文字列 */ char *outstr; /* 出力文字列の長さ */ int len_outstr; int i; outstr = NULL; if( num_arg != 1 ) { return C_UFNC_ERR_TOO_FEW_OR_TOO_MANY_ARGUMENTS; } /* 引数の情報 */ instr = arg_list[0]; len_instr = strlen( instr ); /* ASCII文字なので変換後の長さは入力の長さと同じ */ len_outstr = len_instr; /* * 変換結果用のバッファの獲得 * ・ハンドル内の作業領域に変換結果を持つ */ if( handle->sz_buffer < len_outstr + 1 ) { /* サイズが足りないので拡張する */ char *tmp_ptr; int tmp_sz; tmp_sz = len_outstr + 1; tmp_ptr = (char*)realloc( handle->buffer, tmp_sz ); if( tmp_ptr == NULL ) { return C_UFNC_ERR_INSUFFICIENT_MEMORY; } handle->buffer = tmp_ptr; handle->sz_buffer = tmp_sz; } outstr = handle->buffer; /* 変換 */ for( i=0; i<len_instr; i++ ) { outstr[i] = toupper( instr[i] ); } outstr[i] = '\0'; /* 返却データをセット */ *result = outstr; return C_UFNC_NORMAL_END; } /* 領域解放 */ void defunc_free( struct userhandle_tag *handle, char *result ) { /* 変換結果の領域はハンドルにある作業領域なので解放しない */ if( result != NULL ) { result[0] = '\0'; } return; } |