Thread: dllexport of a structure

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    37

    dllexport of a structure

    is it possible to export a structure from the dll?
    for example, in the DLL:
    Code:
    extern "C"
     {
    typedef struct  __declspec(dllexport) __stdcall CreatedWindows {
    HWND windowhandle[50];
    BOOL Destroyed[50];
    int LastIndex;
    }*CreatedWindowPtr;
    CreatedWindowPtr CreatedWindows;
    
     }
    EXE FILE:

    Code:
    typedef struct  __declspec(dllexport) __stdcall CreatedWindowsPtr {
    HWND windowhandle[50];
    BOOL Destroyed[50];
    int LastIndex;
    }*CreatedWindowPtr;
    CreatedWindowPtr CreatedWindows;
    
    CreatedWindows=(CreatedWindowPtr)GetProcAddress(winDLL,"CreatedWindows");
    the probem is if use it like
    Code:
    memset(CreatedWindows,0,sizeof(CreatedWindows));
    CreatedWindows->LastIndex+=1;
    it crashes with EAccessViolation

    any ideas or?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    A structure is just a way for a compiler to know how to lay things out in memory. So the structure definition belongs in a plain old header file, that will be accessible by both the code for the DLL consumer and producer.

    The next issue is that exporting an instance of some type from a DLL is problematic. If the layout of the structure is not *exactly* the same for both modules, it won't work. Unfortunately, this generally means both pieces of code must be built by the same compiler on the same machine. On the other hand, if you use a compiler directive to align the structure on some boundary *and* only use non-class types (eg: C-style structures), you might be able to get it to work. Anyway, the safest (and most common) solution is to only pass opaque 'handles' to and from the DLL.

    Finally, you are passing to memset a pointer that doesn't point to an actual block of data.

  3. #3
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Sebastiani View Post
    A structure is just a way for a compiler to know how to lay things out in memory. So the structure definition belongs in a plain old header file, that will be accessible by both the code for the DLL consumer and producer.

    The next issue is that exporting an instance of some type from a DLL is problematic. If the layout of the structure is not *exactly* the same for both modules, it won't work. Unfortunately, this generally means both pieces of code must be built by the same compiler on the same machine. On the other hand, if you use a compiler directive to align the structure on some boundary *and* only use non-class types (eg: C-style structures), you might be able to get it to work. Anyway, the safest (and most common) solution is to only pass opaque 'handles' to and from the DLL.

    Finally, you are passing to memset a pointer that doesn't point to an actual block of data.
    No actually I believe the DLL/LIB standard specifies how the data is laid out in memory to avoid this exact issue. Given the same structure definition two different implementations MUST produce the same layout in memory.

  4. #4
    Registered User
    Join Date
    Sep 2009
    Posts
    37
    it does not depend on the memset it also crashs if i only do
    Code:
    CreatedWindows->LastIndex
    the thing is if i declare the struct in dll and exe without export
    it cant be used in the exe , surely not!, the dll is not using same .data segment space than my exe do..

    is it possible to define the structure to a shared memory of the exe and dll so that they can interact, i once red something like this on msdn but i cant remember exactly, it was something about shared process memory or something that 2 processes can use same space of data.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The only effect __declspec(dllexport) on a structure has is that it adds __declspec(dllexport) to every member function. Since the structure has no member functions, it should have no effect at all. (And in any case, you should have __declspec(dllimport) in the EXE version, and you should put the struct in a header with a macro for the declspec that switches appropriately.)
    The __stdcall on the structure is simply wrong.

    Then there's the other problems with your code. The EXE version calls the struct itself *and* the pointer typedef "CreatedWindowsPtr". The DLL version calls the struct and the variable "CreatedWindows". Finally, your memset in the EXE uses sizeof(CreatedWindows), but that picks up the size of the pointer, i.e. it's far too little to zero out the entire structure. Give all your entities distinct names, and you'll be far happier.
    Also, have you actually checked the return value of GetProcAddress? Even under extern "C", I wouldn't be surprised if the compiler mangled the name of the variable such that importing "CreatedWindows" would fail to find anything.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Sep 2009
    Posts
    37
    yeah its true the function can't be found,i didn't managed this function with getlasterror before , it terminates with error 127 cant find function .
    even its a struct and no function ?

    anyway how should i pass data from dll to my process than?
    i think about readprocessmemory or mapping memory to share ...
    but was actually to lazy to search the msdn for those posibillitys, sorry
    Last edited by punkywow; 10-04-2009 at 04:32 AM.

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    37
    how to caluculate the startaddress of the struct?
    ist it the BaseAdress of the proccess + the pointer address to the struct?
    and if yes, are the values of the struct something like this?

    Code:
    sturct mystruct
    {
    WORD x;
    DWORD y;
    WORD z;
    }
    Code:
    offset [structPointer];
    offset [structPointer]+??bytes = WORD x
    offset [structPointer]+??bytes+WORD=  DWORD y
    offset [structPointer]+??bytes+WORD+DWORD=  WORD z
    but how the struct looks like in binary?
    Last edited by punkywow; 10-04-2009 at 05:41 AM.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by punkywow View Post
    yeah its true the function can't be found,i didn't managed this function with getlasterror before , it terminates with error 127 cant find function .
    even its a struct and no function ?
    The API function is called "get procedure address" and yet you can use it to get data. That's just the way it is; the assumption, because it is far more common, is that imported symbols are functions. This is reflected in the function name, return type, and error messages. That doesn't mean it won't work with data. It just means you need to use the correct name.
    You're basically doing the right thing. But the name you type in the source code isn't necessarily the name internally visible in the DLL.

    So let's see. First, do you have to load the DLL dynamically? It's easier to do a load-time link against the DLL. You do this like this:
    Code:
    // dllhdr.h: The interface of the DLL.
    #ifndef GUARD_DLLHDR_H
    #define GUARD_DLLHDR_H
    
    #if defined(BUILD_MY_DLL)
    #define DLLSYM __declspec(dllexport)
    #else
    #define DLLSYM __declspec(dllimport)
    #endif
    
    #if defined(__cplusplus)
    extern "C" {
    #endif
    
    struct MyData
    {
      /* Put data here. */
    };
    
    DLLSYM extern MyData myData;
    
    #if defined(__cplusplus)
    }
    #endif
    
    #endif /*guard*/
    
    --------------------------------------
    // dllimp.cpp: DLL implementation file
    #define BUILD_MY_DLL
    #include "dllhdr.h"
    MyData myData;
    
    -------------------------------------
    // main.cpp: EXE implementation file
    #include "dllhdr.h"
    
    void init()
    {
      memset(&myData, 0, sizeof(myData));
    }
    If you really want to load the DLL with LoadLibrary, it's more complicated.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem referencing structure elements by pointer
    By trillianjedi in forum C Programming
    Replies: 19
    Last Post: 06-13-2008, 05:46 PM
  2. Replies: 5
    Last Post: 02-14-2006, 09:04 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM
  5. C structure within structure problem, need help
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 11-30-2001, 05:48 PM

Tags for this Thread