CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    May 2002
    Posts
    1,798

    Passing a struct to and from a DLL

    I have a DLL that uses a struct that is defined in a separate file, misc.h.
    Code:
    // misc.h
    typedef struct 
    {
    	wstring wsvarstr;
    	wstring wsvarnam;
    	TNT::Matrix<double> Mf;
    	vector<int> vndim;
    	vector<wstring> vwsdxs;
    } sTensor;
    The DLL header:
    Code:
    #include "misc.h"
    
    
    extern "C"
    {
    	void TAIP_API StartMyLib();
    	void TAIP_API DumpTensor(sTensor st);
    	void TAIP_API PrintTensor(sTensor st);
    	void TAIP_API SetTensor(sTensor * st);
    	int TAIP_API ReadVariableMap(wchar_t * varfilepath);
    	void TAIP_API DumpVariableMap();
    	int TAIP_API GetTensorVariable(wstring wsvarnam, sTensor &tensor);
    	void TAIP_API ListVariables();
    	void TAIP_API ListVarStrings();
    
    }
    The DLL methods utilize a class, CVarStack that also uses misc.h to define the struct sTensor.

    What is remarkable to me is that this works at all, but it does. Quite nicely, in fact. Without compiler warnings,
    errors, or leaks.

    My understanding of DLLs is that one should not (cannot ?) pass reference objects as input parameters. In addition,
    C-Linkage prohibits stl input parameters such as wstring and the presumably the stl contents of the struct.

    My questions are:
    1 - Why does this code work on VS 2010, VS2015 (Win 7 64-bit)?
    2 - Can this code be relied upon to work on other Windows machines (Win2K, Vista, Win8, Win10) ?

    Thanks for your comments.
    mpliam

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Passing a struct to and from a DLL

    As long as both sides of the DLL boundary use the same CRT/C++ DLL (not static), and the same compiler settings - then it should work.

    gg

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Passing a struct to and from a DLL

    The issue here is that the dll(s) and all the programs that use it should be compiled with the same compiler version and the same settings. If they are not then you might obtain linkage errors concerning undefined symbols. This is a common issue where a dll has been compiled with version A and the .exe is being compiled with version D.

    Just a comment. Passing sTensor by value may be costly as the struct contains vectors - which will be copied. You may want to consider always passing by pointer as for SetTensor.

    C-Linkage prohibits stl input parameters
    Yes.

    presumably the stl contents of the struct.
    No. A struct can be passed by c-linkage that contains stl contents. Your code does work as you say!

    Can this code be relied upon to work on other Windows machines (Win2K, Vista, Win8, Win10) ?
    If these machines have the appropriate run time system installed for the compiler used.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    May 2002
    Posts
    1,798

    Re: Passing a struct to and from a DLL

    Thank you for your comments. Most helpful. I remain confused on this point. A pointer to a struct is a POD. From that standpoint, it should be OK to use a struct pointer as a parameter to a DLL function (even though there are no pointers in C-linkage?) Some time ago I was here informed never to use a reference variable as an input parameter to a DLL. And I have always been uncertain as to the difference between a reference parameter and a pointer parameter. For example, the difference between
    Code:
    TAIP_API void SetTensor(sTensor * st);
    TAIP_API int GetTensorVariable(wstring wsvarnam, sTensor &tensor);
    Both of which work, but the second one is clearly of reference parameter and is used as such, but both allow for alteration of the input parameter (I think).
    mpliam

  5. #5
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Passing a struct to and from a DLL

    I have a philosophical question related to your issue: my understanding is that the purpose of dynamic linking is mainly decoupling some functionality so that it can be developed/deployed separately. If you are willing to ensure that both your exe and dll will be compiled by the same compiler, with the same dependency and other settings - why not to take one more step and link statically? Than you can share EVERYTHING!
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  6. #6
    Join Date
    May 2002
    Posts
    1,798

    Re: Passing a struct to and from a DLL

    Actually, I have planned to have both available since once the DLL is constructed, it is relatively easy to link just to the library. Just take away the TAIP_API stuff and include the taip.h header. So if I'm simply wanting to update an existing application, I can just have the user install the dll, whereas, if I other developers wish to use the code, the library C wrapper would be preferable. What I am trying to do with this post is to better understand the advantages and limitations of each approach.
    mpliam

  7. #7
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Passing a struct to and from a DLL

    Think of it like this: When classes are passed across module boundaries and their methods are called, where does the code of that method reside? In which module do the classes data members reside - and at what offset?

    std::wstring is a class a with methods and internal data members. While the public interface is defined (by some version of a C++ standard on which it's based), the internal members can (and do) vary wildly from one implementation to another. There can also be extra/alternate methods that the implementation has provided as an extension - or features that can be turned on and off via a define (like iterator validation etc). Packing and alignment also come into play - both sides of the boundary have to agree so that the same offsets are generated when accessing data members. These things are set (including calling convention) for the Win32 API and its structures, which allows multiple languages to utilize it. This agreement is called an ABI - or application binary interface.

    Consider wstring::length(), which has to access internal members in order to return an answer. If this method is not exported as part of a C++ DLL, then the code for length() will reside on both sides of the boundary. The code that is actually used depends on which side the method was called. As long as everything is exactly the same on both sides, it works as expected. Virtual functions behave differently. Assuming the v-table has the same layout on both sides, then calling a virtual will always utilize the code within the boundary that created it - since it's a call through a function pointer, which points into the module which allocated and constructed it.

    With class sizes, data-member offsets, and code which accesses those offsets on both sides of a boundary - you can see how things can go bad very quickly.

    gg

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Passing a struct to and from a DLL

    If you need to share code containing objects between different compilers, then the safe way is to use a technology that defines a binary interface, such as COM.

    Otherwise, if it works, you're getting lucky.

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Passing a struct to and from a DLL

    Quote Originally Posted by Mike Pliam View Post
    Actually, I have planned to have both available since once the DLL is constructed, it is relatively easy to link just to the library. Just take away the TAIP_API stuff and include the taip.h header. So if I'm simply wanting to update an existing application, I can just have the user install the dll, whereas, if I other developers wish to use the code, the library C wrapper would be preferable. What I am trying to do with this post is to better understand the advantages and limitations of each approach.
    The limitation is: crafting DLL requires quite a discipline and clear understanding of why you do what you do.

    Why would you need your code be a DLL, but not a part of EXE? There may be the only answer: your different EXE modules are to access the same piece of code (remember that DLL is just a piece of code dynamically placed into process' memory), and it is critical to not duplicate the code in the EXEs (with a possibility to run into different behavior in case of partial EXE updates). All the other reasons are wrong, whatever you think of it.

    Imagine the situation: You provide a DLL to your customer, and there is the only EXE that links to it. What is the benefit of updating "simply DLL" compared to updating "simply EXE"? A feeling how cool you are? Saving a quarter of megabyte on update transfer?

    Another situation: You provide a DLL to your customer and no matter how many EXEs there are that link to it. You successfully practice a partial update for some period, you move to a fresher version of compiler, a more fresher version, and everything goes just fine. You get used to that feeling of "everything goes just fine". Then you move to the most modern compiler, and BANG! Some of your clients are happy just because they accidentally never do the operations causing the crashes, though other clients unhappily do. You patch those who complained. Now your client versions have diverged, and you have dangerous but sleeping code deployed to the field. And to support all of the clients now it's not enough to "simply update DLL". That's why experienced people invest in crafting installers rather than practicing "simple updates".

    The bottom line: 1) use DLLs only when you really need those, 2) once you decide to go with DLLs, use installer for updates, 3) once you decide to go with installer, test all supported version update combinations (I mean, really TEST EVERYTHING)
    Last edited by Igor Vartanov; January 22nd, 2016 at 04:29 AM.
    Best regards,
    Igor

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Passing a struct to and from a DLL

    All the other reasons are wrong, whatever you think of it
    Don't some Windows call back functions require to be placed in a dll (eg a global hook procedure)?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  11. #11
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Passing a struct to and from a DLL

    Quote Originally Posted by 2kaud View Post
    Don't some Windows call back functions require to be placed in a dll (eg a global hook procedure)?
    Well, in case you mean Windows hooks, doesn't it fit with "different EXE modules are to access the same piece of code"?
    Best regards,
    Igor

  12. #12
    Join Date
    May 2002
    Posts
    1,798

    Re: Passing a struct to and from a DLL

    [QUOTE]A feeling how cool you are?[/QU0TE]

    There's nothing wrong with being cool. You should try it. Seriously, Igor, I find that building code using a wrapper in a DLL forces me to organize my code better than when I throw it all together in linked classes or other types of modules. So I tend not to think of it as a 'cool' way to impress my clients (assuming I had any) with my clever programming skills, but rather a good way to organize my code. If I later decide to update an app, I can just as easily use MS Installer to update both DLL and app, or not. It's not a bad option to have. Further, if I'm not confident that the DLL will work, I can just update the app using the library that was generated with my dll code (with some minor modifications). But all of your points are well-taken. Thanks.
    mpliam

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Passing a struct to and from a DLL

    Quote Originally Posted by Mike Pliam View Post
    There's nothing wrong with being cool. You should try it. Seriously, Igor, I find that building code using a wrapper in a DLL forces me to organize my code better than when I throw it all together in linked classes or other types of modules. So I tend not to think of it as a 'cool' way to impress my clients (assuming I had any) with my clever programming skills, but rather a good way to organize my code. If I later decide to update an app, I can just as easily use MS Installer to update both DLL and app, or not. It's not a bad option to have. Further, if I'm not confident that the DLL will work, I can just update the app using the library that was generated with my dll code (with some minor modifications). But all of your points are well-taken. Thanks.
    You can do all of this with a COM dll and not worry at all about the version of compiler that was used to create the dll.

  14. #14
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Passing a struct to and from a DLL

    Mike, I don't think that just splitting a code base to several binary modules could help to organize the code better. I think that introducing an additional interface, or several ones, without a real necessity only complicates the things. A code that reached a certain level of complexity tends to become even more complex, inefficient, less observable and ultimately vulnerable. That's what I think about this.

    I was charmed by the idea of dynamic code loading when I built my first dll in 1996 and got it working. But two decades of dealing with dlls, COM stuff, etc. now make me be very cautious in questions of architecture and design.
    Best regards,
    Igor

  15. #15
    Join Date
    May 2002
    Posts
    1,798

    Re: Passing a struct to and from a DLL

    I too have been 'charmed', but I certainly respect your opinion and will reconsider how I choose to model my applications.
    mpliam

Page 1 of 2 12 LastLast

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured