我正在开发一个用户定义函数dllib_udf64cpp.dll到我的InterBase 2020数据库。
我正在使用Embarcadero c++ Builder Alexandria 11.1开发和测试从ib_udf64cpp.dll导出的函数.
从ib_udf64cpp.dll导出的fn_SubStr(...)
函数的代码是:
/*===============================================================
fn_SubStr(s, m, n) - Returns the substr starting m ending n in s.
================================================================= */
char* EXPORT fn_SubStr(char* s,
short m, /* starting position */
short n) /* ending position */
{
short i = 0;
short j = 0;
char buffer = (char *)ib_util_malloc(256);
if (m > n || m < 1 || n < 1)
return "Bad parameters: m, n in substring";
else
{
while (*s && i++ < m-1) /* skip */
s++;
while (*s && i++ <= n) /* copy */
buffer[j++] = *s++;
buffer[j] = ' ';
return buffer;
}
}
该函数使用InterBase 2020 API中的ib_util_malloc(256)
函数初始化char* buffer
变量。
udf必须使用ib_util_malloc()
而不是静态数组来分配内存,以便线程安全
当我调试这个函数的代码时:s = "1234567890"; m = 2; n = 7
.
我得到以下buffer = 0x0000000000894690 "234567"
的值:
用于调试的主程序DLLDebugger
ib_udf64cpp.dll具有以下代码:(注意:InterBase建议使用cdecl
呼叫约定)
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdlib.h>
#include <libloaderapi.h>
#include "ufrmDLLDebugger.h"
#include "uIB_UDF64cpp.h"
#pragma comment (lib, "ib_udf64cpp.a")
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma comment(lib, "ib_udf64cpp")
TfrmDLLDebugger *frmDLLDebugger;
const wchar_t* ib_udf64cpp_dll = L"d:/MyFiles/Database/IB_UDF64C/Cpp/Win64/Debug/ib_udf64cpp.dll";
extern "C" __declspec(dllimport) char* __cdecl fn_SubStr(char*, short, short);
typedef char (*SUBSTR)(AnsiString, ShortInt, ShortInt);
SUBSTR fnc_SubStr;
//---------------------------------------------------------------------------
__fastcall TfrmDLLDebugger::TfrmDLLDebugger(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmDLLDebugger::btnExecutarUDFClick(TObject *Sender)
{
int m, n;
AnsiString astr;
HINSTANCE dllhandle = LoadLibrary(ib_udf64cpp_dll);
if (dllhandle == NULL)
{
ShowMessage("Error: The library ib_udf64cpp.dll was not loaded!");
}
else
{ switch(rdgSelUDF->ItemIndex)
{
case -1 : ShowMessage("Select one of the UDFs.");
break;
case 3 : {fnc_SubStr = (SUBSTR)GetProcAddress(dllhandle, "fn_SubStr");
if (Trim(edS->Text) == "")
{
ShowMessage("The [s:] field is empty");
break;
}
if (Trim(edM->Text) == "")
{
ShowMessage("The [m:] field is empty.");
break;
}
if (Trim(edN->Text) == "")
{
ShowMessage("The [n:] field is empty.");
break;
}
astr = AnsiString(edTexto->Text);
m = StrToInt(edM->Text);
n = StrToInt(edN->Text);
astr = fnc_SubStr(astr, m, n);
lblResult->Caption = astr;
break;}
}
}
}
fn_Substr()
赋值给lblResult->Caption
的返回值应该是"234567"而不是" ' "
如何将fn_Substr(s, m, n)
中buffer
的正确返回值分配给lblResult->Caption
?
我将fn_Substr
函数的原型从char* fn_SubStr(char* s, short m, short n)
更改为char* fn_SubStr(char* s, short* m, short* n)
。
我还更改了用于调试导出fn_SubStr()
函数的ib_udf64cpp.dll
的DLLDebugger
程序的代码,如下所示:
const wchar_t* ib_udf64cpp_dll = L"d:/IB_UDF64C/Cpp/Win64/Debug/ib_udf64cpp.dll";
/* Changed code of the DLLDebugger program */
extern "C" __declspec(dllimport) char* __cdecl fn_SubStr(char*, short*, short*);
typedef char* (*SUBSTR)(const char*, short*, short*);
SUBSTR fnc_SubStr;
void __fastcall TfrmDLLDebugger::btnExecuteUDFClick(TObject *Sender)
{
int intvalue;
int* im = new int(0);
int* in = new int(0);
short* sm = new short(0);
short* sn = new short(0);
const char* cstr;
HINSTANCE dllhandle = LoadLibrary(ib_udf64cpp_dll);
if (dllhandle == NULL)
{
ShowMessage("Error: The library ib_udf64cpp.dll was not loaded!");
}
else
{
switch(rdgSelUDF->ItemIndex)
{
case -1 : ShowMessage("Select one of the UDFs.");
break;
case 3 : {fnc_SubStr = (SUBSTR)GetProcAddress(dllhandle, "fn_SubStr");
str = edS->Text;
intvalue = StrToInt(edM->Text);
*sm = intvalue;
intvalue = StrToInt(edN->Text);
*sn = intvalue;
cstr = str.c_str();
cstr = fnc_SubStr(cstr, sm, sn);
lblResult->Caption = cstr;
break;}
}
}
if (im != nullptr)
delete im;
if (in != nullptr)
delete in;
if (sm != nullptr)
delete sm;
if (sn != nullptr)
delete sn;
}
问题似乎解决了。