Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am attempting to export a pointer to an instance of a class that contains a private std::vector member. For some reason, the private vector member is becoming corrupted sometime between construction within the DLL and accessing the object from a client of the DLL. I have narrowed down the problem to the following:
#include <vector>
using namespace std;

size_t const A(sizeof(size_t));
size_t const B(sizeof(myType));
size_t const C(sizeof(vector<myType>));
size_t const D(sizeof(vector<myType>::size_type));

In the above code, A==8, B==40, and D==8 in both the DLL and the client. However, in the DLL C==40, but in the client C==32. How is this possible? What could be the difference? Is there a way to force the built-in vector type to be consistent between the two builds, or do I have to write my own container class? Thanks for any help,

-Jeff
Posted
Updated 21-Jun-11 7:12am
v2

1 solution

The problem may be because you didn't specify calling convention for members of your class. The default convention is __cdecl, but your client DLL may use __stdcall or any other. You should specify convenction like this:

void __cdecl append(bar<size_t> const &inData)

http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx[^]

In general, it is not recommended to export STL objects from DLL, because this may cause problems if modules of your application use different versions of C run-time (CRT).
 
Share this answer
 
Comments
Skippums 21-Jun-11 13:17pm    
Thank you for taking the time to answer my question. Explicitly specifying the calling convention is definitely something that needs to be done. However, I noticed that my current problem stems from the fact that sizeof(std::vector<mytype>) changes between the DLL (where it is 40 bytes) and the client (where it is 32 bytes). I modified my question to be more concise and to reflect this knowlege, but do you have any ideas as to why this would be different between two builds? Thanks,

-Jeff
OlegKrivtsov 21-Jun-11 21:19pm    
Packing options are defined by #pragma pack

http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx

For example, try to add this line before your class:

#pragma pack(1)

.. and the following line after the class declaration:

#pragma pack()
Skippums 22-Jun-11 15:45pm    
Yep... for some reason, when building the DLL in x64 mode, the default packing is on 16-byte boundries. Setting /Zp8 in the compiling options (VS 2008) made both packing options the same. Thanks a lot,

-Jeff
Skippums 26-Jun-11 13:11pm    
I spoke too soon when saying that your solution fixed the glitch. The packing between the two builds is now the same (both are 8), but I am still seeing two different sizes for both std::map and std::vector between my DLL and client. Since our project is due this Friday, I am going to modify my approach to export a bunch of static functions that wrap the class's member functions (since I am using the exported object as a singleton anyway). So, for example, my class has function:

class myClass {
bool IsFunction(const size_t) const;
};

So in the DLL interface file I will have:

myClass *foo;
__declspec(dllexport) IsFunction(const size_t val) {
return foo->IsFunction(val);
}

Perhaps this is the accepted way to do accomplish singleton access anyway, so I don't have to worry about issues like inconsistent objects between builds. However, it adds another level of indirection between the client and DLL, it's more work maintaining the interface (since functions are not magically exported as I create them in myClass), and the client has to load more pointers to objects (instead of loading the single I have to load each function I want to use individually). I am still curios as to why this behavior is occurring. If you have any ideas, I'm more than happy to hear them :).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900