몇가지 맨땅에 해딩하면서 터득한것과 모르는 것 궁금한것
입니다.
1. DLL 프로젝트를 생성한다.
2. ib_util.pas를 Import 한다.
실제 작성입니다.
<Delphi>
function fn_now : double; cdecl;
begin
result := now;
end;
<Scripter>
DECLARE EXTERNAL FUNCTION now
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'fn_now' MODULE_NAME 'DLL명칭';
--- 주석 ---
PRECISION BY VALUE <= 리턴 값을 실제값으로 한다(리턴값이
참조값이나 포인터가 아닌 실값)
<Delphi>
function fn_inttostr(var value : Integer) : pchar; cdecl;
var s : string;
begin
s := inttostr(value);
result := ib_util_malloc(length(s) + 1);
strpcopy(result, s);
end;
<Scripter>
DECLARE EXTERNAL FUNCTION inttostr
INTEGER
RETURNS CSTRING(80) FREE_IT
ENTRY_POINT 'fn_inttostr' MODULE_NAME 'DLL명칭';
--- 주석 ---
- 입력값은 INTEGER POINTER 이다.
(스크립터에서 입렵값 INTEGER는 INTEGER 포인터 라는 의미
delphi : var integer <= integer pointer라는 의미)
- 출력값은 Pchar 타입이다.
RETURNS CSTRING(80) FREE_IT
- 해당출력값을 리턴 받은후 Free 한다. FREE_IT
- Malloc(delphi 에서는 Getmem 이라고 함)은 ib_util_malloc을
써야 한다.
--- 의문점 ---
ib_util_malloc을 사용하여 메모리 할당사이즈가 Dynamic하게
변동하여 설정하는데
CSTRING(80) FREE_IT 이렇게 설정되어 있으면 메모리 해제시
문제가 발생되지
않는가 입니다.
=> 이상없이 작동은 됩니다. Free를 못하여 계속 누적되는지는
확인 방법이 없어서 ㅠㅠ
<DELPHI>
function fn_strtodate(value : pchar) : double; cdecl;
var s : string;
year, month, day : word;
code, v : integer;
begin
s := strpas(value);
result := 0;
if length(s) < 10 then
exit;
val(copy(s, 1, 4), v, code);
if code <> 0 then
exit;
year := v;
val(copy(s, 6, 2), v, code);
if code <> 0 then
exit;
month := v;
val(copy(s, 9, 2), v, code);
if code <> 0 then
exit;
day := v;
result := encodedate(year, month, day);
end;
<SCRIPTER>
DECLARE EXTERNAL FUNCTION STRTODATETIME
CSTRING(80) CHARACTER SET NONE
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'fn_strtodatetime' MODULE_NAME 'DLL명칭';
--- 주석 ---
- 입력값은 스트링포인터(pchar)입니다
스크립터에서는 CSTRING(80)
- PRECISION BY VALUE <= 리턴 값을 실제값으로 한다(리턴값이
참조값이나 포인터가 아닌 실값)
--- 의문점 ---
- 입력값이 VARCHAR(80)처럼 VARCHAR일경우 어떻게 하는것인지
모르겠음
여러번 시도(이중포인터 : Array처럼, 참조..)해보았으나
실패하였고
결국 CSTRING 밖에 스트링변수를 줄 수 없다고 잠정 결론
---- 사용시 특이사항 ----
1. ib_util 을 firebird 2.0에서 compile(즉, 본인 컴퓨터의
ib_util.dll이 2.0 Version 일경우)
한것을 1.5에서 쓰면 안됨
=> 1.5에서 사용시 Function Pointer를 찾지 못한다고 함
(이것 땜시 하루 소비 ㅠㅠ)
2. UDF에서 Exception이 일어나면 Connection 자체가 끊긴다
(허무함..)
즉, 상기 UDF을 사용한 Query를 살펴보면
Select inttostr('숫자가 아닌 데이터') from RDB$database;
이런식이면 UDF에서 Exception이 일어나고 SQLERROR발생이
아니라
Connection 자체가 끊긴다는 것입니다.
결국 UDF안에 Exception처리를 철저히 해야 한다는 또한, 사용시
유의하시고요
|