Firebirdで自作UDFを作る時に、引数で文字列を受け取る方法を調べました。
C++でUDFを作るなら、Firebirdの「examples/udf/」にあるfbudfを参考にすると良さそうです。
「examples/udf/fbudf.sql」を見ると、varchar型は「paramdsc*」という型で引数として受け取っています。
--FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function snvl
varchar(100) by descriptor, varchar(100) by descriptor,
varchar(100) by descriptor returns parameter 3
entry_point 'sNvl' module_name 'fbudf';
「paramdsc*」型は「include/ibase.h」に定義があります。
typedef struct paramdsc {
ISC_UCHAR dsc_dtype;
signed char dsc_scale;
ISC_USHORT dsc_length;
short dsc_sub_type;
ISC_USHORT dsc_flags;
ISC_UCHAR *dsc_address;
} PARAMDSC;
「paramdsc*」型で受け取った引数から、実際の文字列を取得するには「examples/udf/fbudf.cpp」にあるinternal::get_any_string_type()関数を使用します。
この関数はtextに文字列を代入して、文字列長(バイト数)を返します。
namespace internal
{
int get_any_string_type(const paramdsc* v, ISC_UCHAR*& text)
{
…
}
}
なお、「ISC_UCHAR」型はは「include/ibase.h」で定義されています。
typedef unsigned char ISC_UCHAR;
使用例
extern "C" __declspec(dllexport) int sample_func(const paramdsc* v) {
ISC_UCHAR* text;
const int len = internal::get_any_string_type(v, text);
文字列の文字コードは、データベースの文字コードになるようです。
自分で使う時はUTF-8の決めうちで問題ありませんが、汎用的な関数を作る時は難しいかもしれません。