Announcement

Collapse
No announcement yet.

DLL -- Multiple Instantiation Problem

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

  • Edwin Knoppert
    replied
    You can't build 'classes' VERY unf. from plain DLL's.
    You can make use of TLSALLOC api to distinghuis threads (wich ****s)


    ------------------
    [email protected]

    Leave a comment:


  • Lance Edmonds
    replied
    As discussed In greater depth by email, variables in DLL's are not automatically visible to the calling application, but they are stored in the same process address-space (hence can be accessed by reference, pointer, etc).

    To implement separate address-spaces would require you to create separate processes (ie, separate programs). You'd then need to use interprocess communication (IPC) and that adds unnecessary overhead and complixity. It defeats the purpose of creating a DLL.

    In addition, it would not solve the array boundary problem evident above.

    To fix your code above, you simply need to check if LENGTH is different from the current array subscript count, and use REDIM PRESERVE to set the new array length to "LENGTH" subscripts accordingly.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Andrew Peskin
    replied
    Lance,

    Is there a way for the DLL calls to be maintained as seperate entities? I.e.: they each maintain their own memory space respectively, their own data, etc?

    This, in my opinion, would clear this up. Is there a way to implement this?

    Thanks for your help.

    Regards,

    Andrew Peskin
    [email protected]

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

    Leave a comment:


  • Lance Edmonds
    replied
    One thing that does stick out with your "faulty" code is the "Length" parameter is not being handled correctly... as you are not doing a REDIM PRESERVE on the array, the second call starts writing to memory that is not contained within the array - this will likely cause a GPF if the second call passes a length parameter that is substantially larger than the initial call.

    ie, in your example, you initially set the array to 5 elements, but then call it and the code assumes that the array is now 15 elements long, yet you did not redim the array for the larger size.

    Are you likely to be calling the code in a multi-threaded environment? If so, you'll need to use a synchronization object (Critical Sections or Mutex's, etc) to stop the static variables being changed by two threads at the same time.

    By the way, WEP is not used/needed in Win32... LIBMAIN is called when the DLL loads and unloads.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Andrew Peskin
    started a topic DLL -- Multiple Instantiation Problem

    DLL -- Multiple Instantiation Problem


    I am having a serious problem with my DLL development. I am developing DLL's for another
    application to call and can not get them to work properly if called multiple times with differing
    parameter values. Here is an example of the calling of the DLL function:

    Code:
    {----------          WORKING EL Indicator Code BEGIN          ----------}
    VARS:  Avg1(0);
    
    DefineDLLFunc: "C:\MyAvg.DLL", INT, "AvgMAIN", FLOAT, FLOAT, LPFLOAT;
    
    Value1 = AvgMAIN( Close, 5, &Avg1 );
    
    Plot1( Avg1,"DLL_1");
    {where the & indicates passing a pointer}
    {----------            WORKING EL Indicator Code END            ----------}
    The above example works fine and produces correct results. When I try the following example
    call, nothing works properly:

    Code:
    {----------          NOT WORKING EL Indicator Code BEGIN          ----------}
    VARS:   Avg1(0),
            Avg2(0);
    
    DefineDLLFunc: "C:\MyAvg.DLL", INT, "AvgMAIN", FLOAT, FLOAT, LPFLOAT;
    
    Value1 = AvgMAIN( Close, 5, &Avg1 );
    Value2 = AvgMAIN( Close, 15, &Avg2 );
    
    Plot1( Avg1,"DLL_1");
    Plot2( Avg2,"DLL_2");
    {----------            NOT WORKING EL Indicator Code END            ----------}
    I think the problem is that I have to maintain an array of data to work on myself. This must
    be a static array, as the function is called iteratively and passed a new data record. I think
    that since this array is static, it is corrupting the second, third, etc. calls. I tried to
    correct this, by breaking the function up into a main portion which handles all of the data
    maintenance and a Calc portion which handles all of the computations. This did not work. Below
    is the actual code from the DLL. If anything jumps out at you as to where I am going wrong, I
    would be extremely appreciative if you could point out the problem to me.

    Thanks in advance.

    Regards,

    Andrew Peskin
    [email protected]

    Code:
    '----------          DLL CODE BEGIN          ----------
    #COMPILE DLL "C:\MyAvg.DLL"            ' Compile to DLL rather than EXE.
    #DIM ALL                               ' Declare variables before use.
    #DEBUG ERROR OFF                       ' Use to Toggle Error
    
    DECLARE FUNCTION AvgCALC( PriceDAT() AS SINGLE, Length AS SINGLE) AS SINGLE
    
    FUNCTION LibMain(   BYVAL hInstance   AS LONG, _
                        BYVAL Reason      AS LONG, _
                        BYVAL Reserved    AS LONG) EXPORT AS LONG
    
      %TRUE = 1    ' Set Constant True
      %FALSE = 0   ' Set Constant False
    
      LibMain = 1                          ' 1 tells WIN that load
                                           ' was a success.
    END FUNCTION
    
    FUNCTION AvgMAIN(     BYVAL Price AS SINGLE,_ 
                          BYVAL Length AS SINGLE,_ 
                          BYVAL ReturnADR AS DWORD)_
                          EXPORT AS INTEGER
    
        STATIC PriceBUFF()  AS SINGLE
        STATIC PriceDAT()   AS SINGLE
        STATIC Newest       AS LONG
        STATIC InitComplete AS LONG
        STATIC PassNum      AS DWORD
        LOCAL  ReturnVAL    AS SINGLE
        LOCAL  Count        AS DWORD
        LOCAL  SINPTR       AS SINGLE PTR
    
        INCR PassNum
    
        IF ( InitComplete = 0 ) THEN
    
           REDIM PriceBUFF(Length-1)
           FOR Count = 0 TO ( Length - 1 )
               PriceBUFF(Count) = 0
           NEXT Count
    
           REDIM PriceDAT(Length-1)
           FOR Count = 0 TO ( Length - 1 )
               PriceDAT(Count) = 0
           NEXT Count
    
           InitComplete = 1
           Newest = -1
           PassNum = 1
        END IF
    
        Newest = ( Newest + 1 ) MOD Length
        PriceBUFF(Newest) = Price
    
        IF ( PassNum >= ( Length + 1 ) ) THEN
    
            FOR Count = 0 TO ( Length - 1 )
                PriceDAT(Count) = PriceBUFF( ((Newest + Length + Count) MOD Length )
    )
            NEXT Count
    
            ReturnVal = AvgCALC( PriceDAT(), Length )
            AvgMAIN = 1
    
        END IF
    
        SINPTR = ReturnADR
        @SINPTR = ReturnVAL
    
    END FUNCTION
    
    FUNCTION AvgCALC( PriceDAT()  AS SINGLE,_
                      Length      AS SINGLE)_
                      AS SINGLE
    
        LOCAL Count      AS DWORD
        LOCAL Sum        AS DOUBLE
        LOCAL ReturnVAL  AS SINGLE
    
        Sum = 0#
        FOR Count = 0 TO ( Length - 1 )
            Sum = ( Sum + PriceDAT( Count ) )
        NEXT Count
    
        ReturnVAL = ( Sum / Length )
    
        AvgCALC = ReturnVAL
    
    END FUNCTION
    
    ' Function WEP tells Windows to unload this DLL.  This function
    ' definition is the same for any DLL.  Certain other run-once
    ' code can be put here as well, like de-allocating objects.
    
    FUNCTION Wep (BYVAL nParameter AS INTEGER) EXPORT AS WORD
    
      Wep = 1                              ' Tells WIN that unload
                                           ' was a success.
    END FUNCTION
    '----------            DLL CODE END            ----------
    ------------------
Working...
X