Announcement

Collapse
No announcement yet.

C Conversion for Dreamweaver Extensions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • C Conversion for Dreamweaver Extensions

    I'm struggling with a 'C' tp PB/DLL6 conversion for some extensions that I'm writing for the MacroMedia dreamweaver product.

    The 'C' looks pretty simple, but the obvious conversion isn't the correct one!

    The 'C' (stripped down a bit for readability) is:

    '-----------------------------------------------------------
    typedef long JSBool;

    typedef JSBool (*JSNative)(JSContext *cx, JSObject *obj, unsigned int argc,
    jsval *argv, jsval *rval);

    /* JSBool JS_DefineFunction(char *name, JSNative call, unsigned int nargs) */
    #define JS_DefineFunction(n, c, a) \
    (mmEnv.defineFunction ? (*(mmEnv.defineFunction))(mmEnv.libObj, n, c, a) \
    : JS_FALSE)

    typedef struct {
    JSObject *libObj;
    JSBool (*defineFunction)(JSObject *libObj, char *name, JSNative call,
    unsigned int nargs);
    .
    .
    } MM_Environment;

    extern MM_Environment mmEnv;
    .
    .
    .
    MM_Init()
    {
    JS_DefineFunction("computeSum", computeSum, 2);
    }

    JSBool
    computeSum(JSContext *cx, JSObject *obj, unsigned int argc,
    jsval *argv, jsval *rval)
    {
    .
    .
    .
    return JS_TRUE;
    }

    '-----------------------------------------------------
    O.k., so JSNative is simply a pointer to a function with 5 arguments - no problem.

    I start to run into problem with the simple-looking line (above):

    JS_DefineFunction("computeSum", computeSum, 2);

    I realise that this function call refers to the previous typedef, so it actually has 4 parameters... a pointer to an object, a pointer to a string, a pointer to a function and an integer.

    Now then, the problems begin. Dreamweaver passes us a pointer to the content of the MMenv structure and lets us copy it to a local structure. I assumed that to call the function, all I needed to do was to take the second DWORD in the structure as a pointer to the function, and to use CALL DWORD.

    My code is:

    Declare Function JS_DefineFunction Alias "JS_DefineFunction" (JSObject As Dword,FunctionName As Asciiz, JSNative As Dword, ByVal nargs As Integer) As Long
    .
    .
    .
    ComputeSumPointer=CodePtr(ComputeSum)
    Call Dword FunctionAddress Using JS_DefineFunction
    (MM_Environment.libobj,"ComputeSum", ComputeSumPointer, 2) To dummy

    .
    .
    Where FunctionAddress is taken from the structure. I even tried double-dereferencing the address, but that's not correct either. Even if I try to walk through the pointers in the (MS C++) debugger by hand, I can't get myself to anything resembling a function.

    I wouldn't be asking this question if i thought that macroMedia were doing something really wierd. They supply the sample code for direct plugging into C comilers, so the syntax and usage is quite standard...

    Can anybody help?

    John

  • #2
    Try using the CDECL keyword in your declaration ...
    Also think that C passes parameters by value per default, while PB's default is BYREF

    Regards
    Gregor

    ------------------

    Comment


    • #3
      Mmmm, that's a bit tangled. If I'm reading it correctly...

      The JS_DefineFunction macro first checks the value of mmEnv.defineFunction. If this is zero, the macro returns JS_FALSE. Otherwise, it uses mmEnv.defineFunction as a pointer to the function to call, and passes the parameter mmEnv.libObj followed by the macro parameters n, c, and a.

      You may well need the CDECL keyword here.

      I believe your JS_DefineFunction declaration should go more like this:
      Code:
      Declare Function JS_DefineFunction Alias "JS_DefineFunction" (BYVAL JSObject As Dword, FunctionName As Asciiz, BYVAL JSNative As Dword, ByVal nargs As DWORD) As Long
      ------------------
      Tom Hanlin
      PowerBASIC Staff

      Comment


      • #4
        Gregor

        Thanks for the swift response.

        I already tried CDECL, with no joy, but I think that the problem is more basic - in my interpretation of the pointer passed to me and how i derive the function address from it.

        The pointer is passed like this, in C:

        MM_InitWrapper(MM_Environment *env, unsigned int envSize) \
        { \
        extern void MM_Init(); \
        \
        char **envPtr = (char **)env; \
        char **mmPtr = (char **)(&mmEnv); \
        char **envEnd = (char **)((char *)envPtr + envSize); \
        char **mmEnd = (char **)((char *)mmPtr + sizeof(MM_Environment)); \
        \
        /* Copy fields from env to mmEnv, one pointer at a time */ \
        while (mmPtr < mmEnd && envPtr < envEnd) \
        *mmPtr++ = *envPtr++; \
        \
        /* If env doesn't define all of mmEnv's fields, set extras to NULL */ \
        while (mmPtr < mmEnd) \
        *mmPtr++ = (char *)0; \
        \
        /* Call user's MM_Init function */ \
        MM_Init(); \
        } \
        John

        ------------------

        Comment


        • #5
          Tom

          Many thanks.

          That explains the ? syntax on the function call line, and point taken about the byvals on the function line.

          That has given me an idea - maybe I need a byval on the function that I use to pick up the pointer to the structure...

          I'll just try it!

          John

          ------------------

          Comment


          • #6
            Tom

            Yes, the byval on the routine that received the pointer which receives the structure works!

            I now correctly identify the address of the function for my call DWORD expression.

            Unfortunately, I am now getting a GPF in the kernel (which the debugger can't touch) when I actually make the function call!

            I'll have to dig a bit further, but it's close.

            John

            ------------------

            Comment


            • #7
              Gregor, Tom

              Many thanks for your help. I had missed off one final CDECL, so that my code was cleaning up the stack, then so was dreamweaver... Bang!

              O.k., the moral is, always use CDECL and BVAL when interfacing in this way.

              Anyone needing some help adding Dreanweaver extensions in VB can give me a call!

              John

              ------------------

              Comment


              • #8
                Originally posted by John Pearson:
                [SNIP]
                Anyone needing some help adding Dreanweaver extensions in VB can give me a call!

                John

                [/B]
                I would be very happy to get a copy of your declares.
                Maybe you would we willing to post to the source code forum?

                --
                Best Regards Peter Scheutz
                Scheutz & Clementsen Design




                ------------------
                Best Regards
                Peter Scheutz

                Comment


                • #9
                  Sure,

                  I have currently only implemented the function registration, value to integer, integer to value, value to string, string to value functions. The remainder are natural extensions.

                  It was simply getting the CDECLs and BYVALs in the correct places that was the hurdle.

                  Give me some time - I'm under quite a bit of pressure at the moment!

                  John

                  ------------------

                  Comment


                  • #10
                    Originally posted by John Pearson:
                    Sure,

                    [SNIP]
                    Give me some time - I'm under quite a bit of pressure at the moment!

                    John

                    Join the club..
                    It will be a little while before I get the time to look into PB+DW so no hurry, just thought I'd show some interest right away. Maybe Javascript will be okay for what we need to do.

                    --
                    Best regards Peter Scheutz
                    Scheutz & Clementsen Design



                    ------------------
                    Best Regards
                    Peter Scheutz

                    Comment


                    • #11
                      Fine

                      Hmm, you can get most things done in Javascript, but there are quite a few reasons for us to go the PB way:

                      1) We are worried about the update delays as DW passes the document back through the various translators, so an option to supercharge it via PB is a useful thing.

                      2) The guy actually developing this is learning java fast, but is more at home with Basic.

                      3) We have some stock (visual) objects/tools already written in VB that we want to use over DW. PB allows us to call these OCXs easily via the JAZZAge products.

                      John

                      ------------------

                      Comment

                      Working...
                      X