none
Passing a structure doesn't work RRS feed

  • Question

  • I call a function in my DLL to initialize a structure address so the DLL gets the same data. 

    When the DLL function runs, I see this:

    The value of sp is 0x149a39e0, which looks right.  How come this address is not assigned to LENS1 in the dll?

    Saturday, December 24, 2016 5:46 PM

Answers

  • Taking out the "*" gives a compiler error:

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = sp;
    }
    1>USERDLL.cpp(77): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'lens1s *' (or there is no acceptable conversion)
    1>          c:\synopsysv14\userdll\userdll\fortranstructures.h(31): could be 'lens1s &lens1s::operator =(const lens1s &)'
    1>          while trying to match the argument list '(lens1s, lens1s *)'

    It looks like LENS1 is declared as type lensls, not lensls* as it should be.

    It looks like something else is screwed up too.  I define a structure in an h file: (JC is an enum = 12)

    struct lens6s {
        double RFLAGS[JC][200];
        int IFLAGS[JC][200];
    } ;
    extern "C" struct lens6s LENS6;

    I include that h file in a cpp file:

    #include "fortranstructures.h"

    Then I try to use IFLAGS:

    extern "C" __declspec( dllexport ) void dllCV( double*CURV, double G[100], int* JFLAG )
    {
        int t = LENS6.IFLAGS[0][0];    
        int j = *JFLAG;                // 1 for YZ curvature, 2 for XZ
        if ( j == 1 ) {
            double *CV = &G[0];            // YZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;
            return;
        } else {
            double *CV = &G[0];            // XZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;                // fixed elsewhere
            return;
        }
    }

    The editor says LENS6 points to lens6s LENS6.  But it won't link:

    1>MyDLLFiles.obj : error LNK2001: unresolved external symbol _LENS6

    What's going on?  I have used similar logic in the main app with no problem.

    Your LENS6 is declared but not defined. In your .cpp file put

    struct lens6s LENS6;
    

    Now your code will link, but you need to specify the contents of LENS6 somewhere.


    David Wilkinson | Visual C++ MVP

    • Marked as answer by DonDilworth Sunday, December 25, 2016 3:54 PM
    Sunday, December 25, 2016 3:10 PM

All replies

  • I call a function in my DLL to initialize a structure address so the DLL gets the same data. 

    When the DLL function runs, I see this:

    The value of sp is 0x149a39e0, which looks right.  How come this address is not assigned to LENS1 in the dll?


    Perhaps you would like to show us some code?

    David Wilkinson | Visual C++ MVP

    Saturday, December 24, 2016 6:00 PM
  • The pictures didn't come through.  How can one paste screenshots into this forum?

    Anyway, the address of the structure gets sent, but the address of the structure in the DLL is never changed

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = *sp;
    }

    sp is correct when I get here, but LENS1 still points somewhere else.

    The content of the structure is indeed updated to that of the calling program.  But if I change anything there, the calling program doesn't know about it.  It looks like the DLL gets its own private copy, which is not what I want.  What am I doing wrong?

    Saturday, December 24, 2016 6:06 PM
  • The pictures didn't come through.  How can one paste screenshots into this forum?

    Anyway, the address of the structure gets sent, but the address of the structure in the DLL is never changed

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = *sp;
    }

    sp is correct when I get here, but LENS1 still points somewhere else.

    The content of the structure is indeed updated to that of the calling program.  But if I change anything there, the calling program doesn't know about it.  It looks like the DLL gets its own private copy, which is not what I want.  What am I doing wrong?

    If LENS1 is a lens1s* pointer the code should be LENS1 = sp;  (no *)

    if LENS1 is a struct then you are not sharing the data.


    //Right way --
    
    lens1s * LENS1 = NULL;  //LENS1 is a pointer
    
    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = sp;
    }
    
    //Wrong way --
    
    lens1s LENS1;  //LENS1 is a struct
    
    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = *sp;
    }
    
    

    • Edited by RLWA32 Saturday, December 24, 2016 6:39 PM
    Saturday, December 24, 2016 6:10 PM
  • @ DonDilworth

    >The pictures didn't come through.  How can one paste screenshots into this forum?

    If you cannot add a picture, maybe your account is "not verified" yet. (A long story... but in short this is an exciting innovative Microsoft's UX for new people on their forums.) You will get this ability in some time, or you can demand your account "blessed" urgently by posting "me too" message in this thread.

    With apologies,

    -- pa

    Sunday, December 25, 2016 1:16 AM
  • Taking out the "*" gives a compiler error:

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = sp;
    }
    1>USERDLL.cpp(77): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'lens1s *' (or there is no acceptable conversion)
    1>          c:\synopsysv14\userdll\userdll\fortranstructures.h(31): could be 'lens1s &lens1s::operator =(const lens1s &)'
    1>          while trying to match the argument list '(lens1s, lens1s *)'

    It looks like something else is screwed up too.  I define a structure in an h file: (JC is an enum = 12)

    struct lens6s {
        double RFLAGS[JC][200];
        int IFLAGS[JC][200];
    } ;
    extern "C" struct lens6s LENS6;

    I include that h file in a cpp file:

    #include "fortranstructures.h"

    Then I try to use IFLAGS:

    extern "C" __declspec( dllexport ) void dllCV( double*CURV, double G[100], int* JFLAG )
    {
        int t = LENS6.IFLAGS[0][0];
        
        int j = *JFLAG;                // 1 for YZ curvature, 2 for XZ
        if ( j == 1 ) {
            double *CV = &G[0];            // YZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;
            return;
        } else {
            double *CV = &G[0];            // XZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;                // fixed elsewhere
            return;
        }
    }

    The editor says LENS6 points to lens6s LENS6.  But it won't link:

    1>MyDLLFiles.obj : error LNK2001: unresolved external symbol _LENS6

    What's going on?  I have used similar logic in the main app with no problem.

    Sunday, December 25, 2016 2:18 PM
  • Taking out the "*" gives a compiler error:

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = sp;
    }

    Then LENS1 is probably a struct and not a pointer as I pointed out in my earlier post, which demonstrated the right way to share the data between a DLL and an EXE.  It also pointed out the wrong way, which results in a private copy of the struct residing in the DLL which is exactly the problem you are contending with.


    • Edited by RLWA32 Sunday, December 25, 2016 3:10 PM
    Sunday, December 25, 2016 3:07 PM
  • Taking out the "*" gives a compiler error:

    extern "C" __declspec( dllexport ) void InitStruct( lens1s* sp )
    {    
        LENS1 = sp;
    }
    1>USERDLL.cpp(77): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'lens1s *' (or there is no acceptable conversion)
    1>          c:\synopsysv14\userdll\userdll\fortranstructures.h(31): could be 'lens1s &lens1s::operator =(const lens1s &)'
    1>          while trying to match the argument list '(lens1s, lens1s *)'

    It looks like LENS1 is declared as type lensls, not lensls* as it should be.

    It looks like something else is screwed up too.  I define a structure in an h file: (JC is an enum = 12)

    struct lens6s {
        double RFLAGS[JC][200];
        int IFLAGS[JC][200];
    } ;
    extern "C" struct lens6s LENS6;

    I include that h file in a cpp file:

    #include "fortranstructures.h"

    Then I try to use IFLAGS:

    extern "C" __declspec( dllexport ) void dllCV( double*CURV, double G[100], int* JFLAG )
    {
        int t = LENS6.IFLAGS[0][0];    
        int j = *JFLAG;                // 1 for YZ curvature, 2 for XZ
        if ( j == 1 ) {
            double *CV = &G[0];            // YZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;
            return;
        } else {
            double *CV = &G[0];            // XZ Curvature
            double cv = *CV;
            *CURV = cv/2.0;                // fixed elsewhere
            return;
        }
    }

    The editor says LENS6 points to lens6s LENS6.  But it won't link:

    1>MyDLLFiles.obj : error LNK2001: unresolved external symbol _LENS6

    What's going on?  I have used similar logic in the main app with no problem.

    Your LENS6 is declared but not defined. In your .cpp file put

    struct lens6s LENS6;
    

    Now your code will link, but you need to specify the contents of LENS6 somewhere.


    David Wilkinson | Visual C++ MVP

    • Marked as answer by DonDilworth Sunday, December 25, 2016 3:54 PM
    Sunday, December 25, 2016 3:10 PM
  • You made my day.  Have a nice turkey dinner.
    Sunday, December 25, 2016 3:54 PM