Linux中的Firebird UDF设置为通过引用返回时崩溃服务器

我正在尝试在Linux中为firebird创build一些简单的UDF(用GCC编译的C语言)。 问题是,当我把“返回机制”设置为“引用”的时候,当我调用这个函数的时候,服务器崩溃了。 当它是“按价值”,没有问题。

这里是我尝试写在C中的函数:

这个工作:

double round(double *); double round(val) double *val; { *val = *val * 100; *val = (*val>= 0) ? (long)(*val + 0.5) : (long)(*val - 0.5); *val = *val / 100; return *val; } 

但是这个在调用时崩溃了服务器:

 char * proper_case(str) char * str; { return str; } 

这里是DDL:

 DECLARE EXTERNAL FUNCTION "ROUND" DOUBLE PRECISION RETURNS DOUBLE PRECISION BY VALUE ENTRY_POINT 'round' MODULE_NAME 'my_udfs.so'; DECLARE EXTERNAL FUNCTION PROPCASE CSTRING(10000) RETURNS CSTRING(10000) FREE_IT ENTRY_POINT 'proper_case' MODULE_NAME 'my_udfs.so'; 

我用第二个函数调用:

 select propcase('abrakadabra') from rdb$database; 

火鸟服务器崩溃,唯一的错误信息是:

 Statement failed, SQLSTATE = -902 Error reading data from the connection. 

有人可以build议吗? 任何帮助将不胜感激!

我忘记提供的唯一信息是我编译.so文件的方式(可能是这里的关键):

 gcc -c -O -fpic my_udf.c ld -G my_udf.o -lm -lc -o my_udf.so cp my_udf.so /usr/lib/firebird/2.1/UDF/my_udfs.so 

AFAIK,Firebird会在调用之后尝试释放参数和返回值(因为它不知道你在函数内部做了什么,并且你已经声明了你的返回值为FREE_IT ),所以你需要为返回值分配空间在返回之前。 你必须用ib_util_malloc()调用分配内存,所以它看起来像(甚至没有试图编译它,但它应该给你的一般想法):

 char * proper_case(str) char * str; { char* ret = (char*)ib_util_malloc(strlen(str) + 1); strcpy(ret, str); // or run the actual logic here return ret; } 

编辑:我发现在UDF lib中建立的Firebird的一个例子:

 pChar EXPORT IB_UDF_lower(const char *s) { if (!s) return 0; char* buf = (char *) ib_util_malloc(strlen(s) + 1); char* p = buf; while (*s) { if (*s >= 'A' && *s <= 'Z') { *p++ = *s++ - 'A' + 'a'; } else *p++ = *s++; } *p = '\0'; return buf; } 

谢谢Mark,你是对的。 编译/链接有问题。

这不完全是一个答案,但我如何设法解决这个问题。

我正在用这些命令编译UDF:

 gcc -c -O -fpic my_udf.c ld -G my_udf.o -lm -lc -o my_udf.so cp my_udf.so /usr/lib/firebird/2.1/UDF/my_udfs.so 

没有错误,firebird服务器崩溃也没有错误状态。 所以我打开了Python,并尝试以下内容:

 from ctypes import * libc = CDLL("path/to/my_udf.so") libc.IB_UDF_lower("abrakadabra") 

Python抛出关于非现有函数“ib_util_malloc”的错误。 所以我把它换成“malloc”,一切正常。

我仍然不知道自己做错了什么,但是由于GCC不给我任何错误,我想这是一个链接问题。