Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass std::string to a DLL?

I separated a code fragment into a DLL because it will be frequently updated and in this way it should be easier to deploy.

But I have questions about what I can do and what I cannot do with a DLL.

  1. Can I pass a std:string or a CString to a DLL?
  2. Can I pass a pointer to a struct with std::string members and fill it in a DLL?
  3. Can a DLL return a pointer to a struct allocated there? Will it be valid? Can I delete it after?
  4. What should better to pass, a std::String or a Cstring?

Thanks !

like image 324
bratao Avatar asked Mar 18 '11 02:03

bratao


People also ask

Is std::string a part of STL?

It is part of STL indeed. And std::string is just basic_string<char> typedef. It is container, specialized (not in C++ "specialization" meaning :) ) for data storage with string semantics.

Is std::string movable?

Yes, std::string (since C++11) is able to be moved i.e. it supports move semantics.

Is std::string the same as string?

There is no functionality difference between string and std::string because they're the same type. That said, there are times where you would prefer std::string over string .

Is std::string contiguous?

The std::string class manages the underlying storage for you, storing your strings in a contiguous manner. You can get access to this underlying buffer using the c_str() member function, which will return a pointer to null-terminated char array.


2 Answers

You have a choice to make:

  • Tightly coupled DLL: The DLL is built with the exact same compiler version, packing and calling convention settings, library options as the application, and both dynamically link to the runtime library (/MD compiler option). This lets you pass objects back and forth including STL containers, allocate DLL objects from inside the application, derive from base classes in the other module, do just about everything you could without using DLLs. The disadvantage is that you can no longer deploy the DLL independently of the main application. Both must be built together. The DLL is just to improve your process startup time and working set, because the application can start running before loading the DLL (using the /delayload linker option). Build times are also faster than a single module, especially when whole program optimization is used. But optimization doesn't take place across the application-DLL boundary. And any non-trivial change will still require rebuilding both.

  • Loosely coupled: The application doesn't depend on the class layout of objects defined by the DLL. You use only highly compatible data types: primitive types, pointers, function pointers, and user-defined types made up of these elements. Classes inherit from a base class which defines interface and has no data members and no non-virtual functions (this means no constructors and no sharing of standard library objects such as std::string or CString). All allocation and object creation must be done through a factory function. Memory must be deallocated from the module which allocated it. Code and data are separated. The header file explicitly states the calling convention of each exported function and packing of each structure allowed to cross module boundaries. The advantage is that the DLL and application can be updated completely independently. You can rebuild one with a new runtime library, new compiler version, or even in a completely new language, and don't have to even touch the other.

I always advise using the loosely coupled approach.

like image 53
Ben Voigt Avatar answered Sep 30 '22 21:09

Ben Voigt


There is a danger when passing anything into and out of a DLL if it's based on a template. Compiler options can affect the layout of the object, and a template class can't be confined to a single compilation unit; some of it will be distributed to the calling module.

In the case of a string, I would pass a const char * (or const wchar_t * or const TCHAR *) and do the conversion to std::string or CString on the other side of the interface, within the DLL.

like image 42
Mark Ransom Avatar answered Sep 30 '22 21:09

Mark Ransom