Developing cfx tags in Borland C++ Builder

Ask a Question related to Coldfusion - Advanced Techniques, Design and Development.

  1. #1

    Default 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

  2. Similar Questions and Discussions

    1. 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...
    2. 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...
    3. 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...
    4. 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...
    5. 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...
  3. #2

    Default 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

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139