DLL and STL in function parameters
-
Hello, I wanted to move the implementation of some of my functions to a DLL and update only the DLL and do not touch the GUI.I normally use STL and i learnt that STL and DLLs together can create some problems. Lets say i have such a function below and that Point3D vector will be given from another DLL (which deals IO stuff). 1. DLL
TEST_API double calcPerimeter(const std::vector<Point3D>& pts)
{
double p = 0.0;
for(std::size_t i = 1; i < pts.size(); ++i)
p+= calcDistance(pts[i-1],pts[i], false);p = sqrt(p); return p;
}
2. DLL i want to export a std::vector from a function. Will this work or even if it works under what conditions? By the way, I will use the same compiler for exe and dlls. How will you implement above? (a very simple data holder (Point3D vector) in a DLL and in another DLL just bunch of functions which operates on that data? Best Regards. Bekir.
-
Hello, I wanted to move the implementation of some of my functions to a DLL and update only the DLL and do not touch the GUI.I normally use STL and i learnt that STL and DLLs together can create some problems. Lets say i have such a function below and that Point3D vector will be given from another DLL (which deals IO stuff). 1. DLL
TEST_API double calcPerimeter(const std::vector<Point3D>& pts)
{
double p = 0.0;
for(std::size_t i = 1; i < pts.size(); ++i)
p+= calcDistance(pts[i-1],pts[i], false);p = sqrt(p); return p;
}
2. DLL i want to export a std::vector from a function. Will this work or even if it works under what conditions? By the way, I will use the same compiler for exe and dlls. How will you implement above? (a very simple data holder (Point3D vector) in a DLL and in another DLL just bunch of functions which operates on that data? Best Regards. Bekir.
Provided you use the same compiler and probably linker, the same compiler and linker settings (with a few exceptions to do with building DLLs) then you can do what you want without any problems. The fun comes with DLLs when people wonder why they can't link C++ DLLs with EXEs written in C or on another C++ compiler. Cheers, Ash
-
Hello, I wanted to move the implementation of some of my functions to a DLL and update only the DLL and do not touch the GUI.I normally use STL and i learnt that STL and DLLs together can create some problems. Lets say i have such a function below and that Point3D vector will be given from another DLL (which deals IO stuff). 1. DLL
TEST_API double calcPerimeter(const std::vector<Point3D>& pts)
{
double p = 0.0;
for(std::size_t i = 1; i < pts.size(); ++i)
p+= calcDistance(pts[i-1],pts[i], false);p = sqrt(p); return p;
}
2. DLL i want to export a std::vector from a function. Will this work or even if it works under what conditions? By the way, I will use the same compiler for exe and dlls. How will you implement above? (a very simple data holder (Point3D vector) in a DLL and in another DLL just bunch of functions which operates on that data? Best Regards. Bekir.
Additional to what Aescleal wrote, do not use STL across library boundaries if you can avoid it! Unfortunately, it's not guaranteed to be binary compatible and can cause you troubles in the long run. Nasty things can happen when you mix compilers or STL versions, hard to debug. Cheers :)
-
Additional to what Aescleal wrote, do not use STL across library boundaries if you can avoid it! Unfortunately, it's not guaranteed to be binary compatible and can cause you troubles in the long run. Nasty things can happen when you mix compilers or STL versions, hard to debug. Cheers :)
-
Thank you for the answers. I will look at options to remove that STL vector, any recommendations ? Bekir.
I hate to say it, but in this case use only fundamental/primitive types and pointers. For example use as arguments buffer and buffer size/elements, avoid unnecessary data copying, e.g. caller provides buffers big enough to hold results. You gave a function using STL, here is a slight variation of it:
TEST_API double calcPerimeter(const Point3D* pPoints, int nElements)
/M
-
I hate to say it, but in this case use only fundamental/primitive types and pointers. For example use as arguments buffer and buffer size/elements, avoid unnecessary data copying, e.g. caller provides buffers big enough to hold results. You gave a function using STL, here is a slight variation of it:
TEST_API double calcPerimeter(const Point3D* pPoints, int nElements)
/M
Hi Moak, I was about to write that function and ask :) and saw your message. When I use, then i can safely give the vector's first element as reference to the function and vector's size.
std::vector points;
....if(!points.empty())
calcPerimeter(&points[0], static_cast(points.size());Best Regards. Bekir.
-
Hi Moak, I was about to write that function and ask :) and saw your message. When I use, then i can safely give the vector's first element as reference to the function and vector's size.
std::vector points;
....if(!points.empty())
calcPerimeter(&points[0], static_cast(points.size());Best Regards. Bekir.
There's another option here which probably means changing your design... From the small amount of code you've posted it looks to me like you're trying to handle 3D paths of some sort. Instead of exposing a set of functions which operate on vectors of points, how about defining an interface?
class path
{
public:
virtual ~path();virtual double length() const = 0; virtual double distance\_from( const point &p ) const = 0;
};
Then you can write all your client code that deals with paths in terms of that interface. You can then impelement paths in your DLL or pass them into other DLLs and not have to worry about copying, assignment and all the other DLLy problems (such as exporting functions - THIS is the big plus for me...). So say you implement a concrete path in your DLL:
class vector_path : public path
{
public:
vector_path( const std::vector<point *> &points_defining_path );
~vector_path();virtual double length() const; virtual double distance\_from( const point &p ) const; private: std::vector points\_defining\_path\_;
};
you can export a pair of creation/deletion functions:
PATH_EXPORT path *create_vector_path( const point **start_pts_in_path, const point **end_pts_in_path )
{
std::vector pts_in_path( start_pts_in_path, end_pts_in_path );
return new (no_throw) vector_path( pts_in_path );
}PATH_EXPORT void cleanup_path( path *to_cleanup )
{
delete to_cleanup;
}This gives you a nice interface you can use without worrying about lobbing vectors around as you're dealing with paths, a much higher level concept. Cheers, Ash
-
There's another option here which probably means changing your design... From the small amount of code you've posted it looks to me like you're trying to handle 3D paths of some sort. Instead of exposing a set of functions which operate on vectors of points, how about defining an interface?
class path
{
public:
virtual ~path();virtual double length() const = 0; virtual double distance\_from( const point &p ) const = 0;
};
Then you can write all your client code that deals with paths in terms of that interface. You can then impelement paths in your DLL or pass them into other DLLs and not have to worry about copying, assignment and all the other DLLy problems (such as exporting functions - THIS is the big plus for me...). So say you implement a concrete path in your DLL:
class vector_path : public path
{
public:
vector_path( const std::vector<point *> &points_defining_path );
~vector_path();virtual double length() const; virtual double distance\_from( const point &p ) const; private: std::vector points\_defining\_path\_;
};
you can export a pair of creation/deletion functions:
PATH_EXPORT path *create_vector_path( const point **start_pts_in_path, const point **end_pts_in_path )
{
std::vector pts_in_path( start_pts_in_path, end_pts_in_path );
return new (no_throw) vector_path( pts_in_path );
}PATH_EXPORT void cleanup_path( path *to_cleanup )
{
delete to_cleanup;
}This gives you a nice interface you can use without worrying about lobbing vectors around as you're dealing with paths, a much higher level concept. Cheers, Ash
Dear Ash, Thank you for such a detailed answer, at first i thought i can have data set and implement different operations on that data set (Area, Perimeter and some clipping operations) Defining an interface and hide the data in concrete classes and use interface functions to operate on is another perhaps better way. I had already looked into below link. Mature Approach part is similar to yours except virtual destructor is replaced by a Release() method and Smart Pointer calls that function for clean-up. HowTo: Export C++ classes from a DLL[^] Again thank you for the answers. Best Regards.
-
Dear Ash, Thank you for such a detailed answer, at first i thought i can have data set and implement different operations on that data set (Area, Perimeter and some clipping operations) Defining an interface and hide the data in concrete classes and use interface functions to operate on is another perhaps better way. I had already looked into below link. Mature Approach part is similar to yours except virtual destructor is replaced by a Release() method and Smart Pointer calls that function for clean-up. HowTo: Export C++ classes from a DLL[^] Again thank you for the answers. Best Regards.
If you go for that style of solution there's plenty you could do to improve the safety of the solution I outlined - private destructor, cleanup function a friend of the interface so it can be deleted, quick typedef for shared_ptr and a helper to create them. If you need some more help with the details please ask another question and I can bore you further! Cheers, Ash