locked
Can STL vector cross DLL boundary? RRS feed

  • Question

  • Can I have the following method in a DLL and call it from a Client, like this?

    // DLL file

    void DllFunction (std::vector<int> &B)
    {
      B.push_back(1);
    }

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

    // Client file

    void SomeFunction ()
    {
      std::vector<int> A;

      DllFunction(A);
    }

    When I try to do this I get a runtime error in _CrtIsValidHeapPointer (dbgheap.c) when SomeFunction returns.  I figured the problem is that the DLL allocates the memory and the Client is trying to free it and that's bad.

    So, what do people do when they want to pass an STL vector as a reference parameter to a DLL?  Cannot such a basic thing be done?

    I've made sure my runtime libraries are the same for the dll and the client (/MTd).

    Tuesday, February 14, 2006 7:16 PM

Answers

  • If your DLL and Exe use the static CRT, this won't work properly. Use the DLL CRT in both Exe and DLL. (/MD or /MDd)

     Unjedai wrote:

    Can I have the following method in a DLL and call it from a Client, like this?

    // DLL file

    void DllFunction (std::vector<int> &B)
    {
      B.push_back(1);
    }

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

    // Client file

    void SomeFunction ()
    {
      std::vector<int> A;

      DllFunction(A);
    }

    When I try to do this I get a runtime error in _CrtIsValidHeapPointer (dbgheap.c) when SomeFunction returns.  I figured the problem is that the DLL allocates the memory and the Client is trying to free it and that's bad.

    So, what do people do when they want to pass an STL vector as a reference parameter to a DLL?  Cannot such a basic thing be done?

    I've made sure my runtime libraries are the same for the dll and the client (/MTd).

    Tuesday, February 14, 2006 10:16 PM

All replies

  • If your DLL and Exe use the static CRT, this won't work properly. Use the DLL CRT in both Exe and DLL. (/MD or /MDd)

     Unjedai wrote:

    Can I have the following method in a DLL and call it from a Client, like this?

    // DLL file

    void DllFunction (std::vector<int> &B)
    {
      B.push_back(1);
    }

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

    // Client file

    void SomeFunction ()
    {
      std::vector<int> A;

      DllFunction(A);
    }

    When I try to do this I get a runtime error in _CrtIsValidHeapPointer (dbgheap.c) when SomeFunction returns.  I figured the problem is that the DLL allocates the memory and the Client is trying to free it and that's bad.

    So, what do people do when they want to pass an STL vector as a reference parameter to a DLL?  Cannot such a basic thing be done?

    I've made sure my runtime libraries are the same for the dll and the client (/MTd).

    Tuesday, February 14, 2006 10:16 PM
  • Also, STL objects are not designed to be binary compatible (which is what you need to rely on being able to point to the same instance in two different binaries).
    Tuesday, February 14, 2006 10:24 PM
  • I strongly agree to that. Just the next servicepack might break binary compatibility...
    Wednesday, February 15, 2006 8:06 AM
  • I found something that hopefully will be a solution for me in "Effective C++" Third Edition by Scott Meyers (Item 18, page 82)

    "An especially nice feature of tr1::shared_ptr is that it automatically uses its per-pointer deleter to eliminate another potential client error, the "cross-DLL problem."  This problem crops up when an object is created using new in one dynamically linked library (DLL) but is deleted in a different DLL.  On many platforms, such cross-DLL new/delete pairs lead to runtime errors.  tr1:;shared_ptr avoids the problem, because its default deleter uses delete from the same DLL where the tr1::shared_ptr is created."

    So, I could modify my code such that all allocations and deletions occur in either the client or the DLL but not both, and pass a shared pointer to cross the boundary.  I haven't tried this yet but will soon.  I'll probably be using a boost shared pointer.  Does Visual Studio provide any tr1 stuff?
    Thursday, June 29, 2006 2:48 PM