Ask a Question related to Coldfusion - Advanced Techniques, Design and Development.
-
RobinWhitehead #1
Developing cfx tags in Borland C++ Builder
Hi,
I have been trying to get a cfx tag written in BCB (v5) to work with cfmx 6.1.
The tag compiles, but it throws errors when I try and use it in a .cfm file.
I have tried various different calling definitions on the exported
ProcessTagRequest() function (WINAPI, __stdcall, and none), but none of them
seem to produce a useable cfx tag.
I have managed to get a cfx tag working using Delphi, but I really want to get
it working using BCB (I'm a C++ programmer)
Are there any settings in the project options that need to be set for the dll
to be created correctly? I have read somewhere that the problem may be related
to the vtables.
Any help would be most appreciated.
Cheers,
Rob
RobinWhitehead Guest
-
Report Builder (expression builder syntax)
I'm trying to create a calculated field that will compare the values from one query field and depending on the values will assign a value to the... -
Using ParseChildren attribute to load child tags - VS removes tags
I am building a poll control, nested in the tag I have child tags to setup the poll options. Everything works fine, but when I edit a property in... -
where to post: problem compiling ruby1.8 with borland c 5.5
The ruby-dev is a Japanese list, isn't it? So where should I post this bug? ----- Forwarded message from KONTRA Gergely... -
problem compiling ruby1.8 with borland c 5.5
Hi! I've problem compiling ruby-preview 1.8.0-preview3 on win98. After doing bcc32\configure.bat, when I type make, it simply doesn't find the... -
Oracle OCI programming and Borland C++ Builder
Afternoon, this is an answer not a question :o) As you may know, Oracle dropped support for Borland Compilers in OCI some time back. Well, it... -
RobinWhitehead #2
Re: Developing cfx tags in Borland C++ Builder
OK, I got this working, so I thought I'd post the solution in case anyone else
is trying to do the same thing.
1) First paste the code at the end of this post into a file called cfxapid.pas
(it's the Delphi wrapper written by Leonid Fofanov)
2) Include this file into your DLL project (it will autocreate a .hpp file for
you)
3) In the .cpp file which you put your ProcessTagRequest function, include the
cfxapid.hpp file
4) you need to declare the ProcessRequestFunction as:
void __cdecl ProcessTagRequest( TCFXRequest* pRequest )
{
}
5) export the function like this:
extern "C" __declspec(dllexport) void __cdecl ProcessTagRequest(TCFXRequest
*Request);
6) BCB will actually export the function as _ProcessTagRequest, so don't
forget to put the leading '_' when you declare the entry point when you
register the cfx_tag in the ColdFusion administrator.
Tested with BCB 5 and CFMX 6.1
Cheers,
Rob
{$R-,Q-,X+,W-,D-,L-,Y-}
{================================================= ========}
{ Cold Fusion extensions classes for Delphi (CFX_D) }
{ }
{ by Leonid Fofanov [email]lfofanov@hotmail.com[/email] }
{ ================================================== ======}
unit cfxapid;
interface
const
CFX_STRING_NOT_FOUND = -1;
type
// Basic wrapper class, translates Pascal methods calls to C++ methods calls
TCFXBaseClass = class
private
function callMethod0(index: integer): integer;
function callMethod1(parm1, index: integer): integer;
function callMethod2(parm1, parm2, index: integer): integer;
function callMethod3(parm1, parm2, parm3, index: integer): integer;
end;
TCFXStringSet = class(TCFXBaseClass)
function AddString(S: PChar):integer;
function GetCount: integer;
function GetString(Index: integer): PChar;
function GetIndexForString(S: PChar): integer;
end;
TCFXQuery = class(TCFXBaseClass)
function GetName: PChar;
function GetRowCount: integer;
function GetColumns: TCFXStringSet;
function GetData(Row, Column: integer): PChar;
function AddRow: integer;
procedure SetData(Row, Column: integer; Data: PChar);
end;
TCFXException = class(TCFXBaseClass)
function GetError: PChar;
function GetDiagnostics: PChar;
end;
TCFXRequest = class(TCFXBaseClass)
function AttributeExists(AttrName: PChar): boolean;
function GetAttribute(AttrName: PChar): PChar;
function GetAttributeList: TCFXStringSet;
function GetQuery: TCFXQuery;
function GetSetting(SettingName: PChar): PChar;
procedure Write(S: PChar);
procedure SetVariable(Name: PChar; Value: PChar);
function AddQuery(Name: PChar; Columns: TCFXStringSet): TCFXQuery;
function Debug: boolean;
procedure WriteDebug(Output: PChar);
function CreateStringSet: TCFXStringSet;
procedure ThrowException(Error, Diagnostics: PChar);
procedure ReThrowException(e: TCFXException);
procedure SetCustomData(Data: pointer);
function GetCustomData: pointer;
end;
implementation
//================================================== =======
// TCFXBaseClass class
//================================================== =======
function TCFXBaseClass.callMethod0(index: integer): integer;
asm
push ebx
mov ebx, index
mov eax, Self
mov ecx, eax
mov edx, [eax]
call dword ptr [edx+ebx]
pop ebx
end;
function TCFXBaseClass.callMethod1(parm1: integer; index: integer): integer;
asm
push ebx
mov ebx, index
push parm1
mov eax, Self
mov ecx, eax
mov edx, [eax]
call dword ptr [edx+ebx]
pop ebx
end;
function TCFXBaseClass.callMethod2(parm1, parm2, index: integer): integer;
asm
push ebx
push parm2
push parm1
mov ebx, index
mov eax, Self
mov ecx, eax
mov edx, [eax]
call DWORD PTR [edx+ebx]
pop ebx
end;
function TCFXBaseClass.callMethod3(parm1, parm2, parm3, index: integer):
integer;
asm
push ebx
push parm3
push parm2
push parm1
mov ebx, index
mov eax, Self
mov ecx, eax
mov edx, [eax]
call DWORD PTR [edx+ebx]
pop ebx
end;
//================================================== =======
// TCFXRequest class
//================================================== =======
function TCFXRequest.AttributeExists(AttrName: PChar): boolean;
begin
Result:=boolean(callMethod1(integer(AttrName), 4));
end;
function TCFXRequest.GetAttribute(AttrName: PChar): PChar;
begin
Result:=PChar(callMethod1(integer(AttrName), 8));
end;
function TCFXRequest.GetAttributeList: TCFXStringSet;
begin
Result:=TCFXStringSet(callMethod0(12));
end;
function TCFXRequest.GetQuery: TCFXQuery;
begin
Result:=TCFXQuery(callMethod0(16));
end;
function TCFXRequest.GetSetting(SettingName: PChar): PChar;
begin
Result:=PChar(TCFXQuery(callMethod1(integer(Settin gName), 20)));
end;
procedure TCFXRequest.Write(S: PChar);
begin
callMethod1(integer(S), 24);
end;
procedure TCFXRequest.SetVariable(Name: PChar; Value: PChar);
begin
callMethod2(integer(Name), integer(Value), 28);
end;
function TCFXRequest.AddQuery(Name: PChar; Columns: TCFXStringSet):
TCFXQuery;
begin
Result:=TCFXQuery(callMethod2(integer(Name), integer(Columns), 32));
end;
function TCFXRequest.Debug: boolean;
begin
Result:=boolean(callMethod0(36));
end;
procedure TCFXRequest.WriteDebug(Output: PChar);
begin
callMethod1(integer(Output), 40);
end;
function TCFXRequest.CreateStringSet: TCFXStringSet;
begin
Result:=TCFXStringSet(callMethod0(44));
end;
procedure TCFXRequest.ThrowException(Error, Diagnostics: PChar);
begin
callMethod2(integer(Error), integer(Diagnostics), 48);
end;
procedure TCFXRequest.ReThrowException(e: TCFXException);
begin
callMethod1(integer(e), 52);
end;
procedure TCFXRequest.SetCustomData(Data: pointer);
begin
callMethod1(integer(Data), 56);
end;
function TCFXRequest.GetCustomData: pointer;
begin
Result:=Pointer(callMethod0(60));
end;
//================================================== =======
// TCFXStringSet class
//================================================== =======
function TCFXStringSet.AddString(S: PChar):integer;
begin
Result:=callMethod1(integer(S), 4);
end;
function TCFXStringSet.GetCount: integer;
begin
Result:=callMethod0(8);
end;
function TCFXStringSet.GetString(Index: integer): PChar;
begin
Result:=PChar(callMethod1(Index, 12));
end;
function TCFXStringSet.GetIndexForString(S: PChar): integer;
begin
Result:=callMethod1(integer(S), 16);
end;
//================================================== =======
// TCFXQuery class
//================================================== =======
function TCFXQuery.GetName: PChar;
begin
Result:=PChar(callMethod0(4));
end;
function TCFXQuery.GetRowCount: integer;
begin
Result:=callMethod0(8);
end;
function TCFXQuery.GetColumns: TCFXStringSet;
begin
Result:=TCFXStringSet(callMethod0(12));
end;
function TCFXQuery.GetData(Row, Column: integer): PChar;
begin
Result:=PChar(callMethod2(Row, Column, 16));
end;
function TCFXQuery.AddRow: integer;
begin
Result:=callMethod0(20);
end;
procedure TCFXQuery.SetData(Row, Column: integer; Data: PChar);
begin
callMethod3(Row, Column, integer(Data), 24);
end;
//================================================== =======
// TCFXException class
//================================================== =======
function TCFXException.GetError: PChar;
begin
Result:=PChar(callMethod0(4));
end;
function TCFXException.GetDiagnostics: PChar;
begin
Result:=PChar(callMethod0(8));
end;
end.
RobinWhitehead Guest



Reply With Quote

