views:

103

answers:

6

I have not worked with static libraries before, but now I need to.

Scenario:

I am writing a console app in Unix. I freely use std::string everywhere because it's easy to do so. However, I recently found out that I have to support it in Windows and a third party application would need API's to my code (I will not be sharing source, just the DLL).

With this in mind, can I still use std::string everywhere in my code but then provide them with char * when I code the API's? Would that work?

+1  A: 

Why not just provide them with std::string?
It's standard C++, and I'd be very suprised if they didn't support it.

Ink-Jet
Well if someone needs to interface with that static library in a language that isn't C++ then they're going to have a hard time.
Peter Alexander
Hadn't thought about that - very good point.
Ink-Jet
Of course they support it. Even on C++, the implementations are possibly different, forcing the client to use "your" std::string everywhere. Now imagine if two libraries did that..
peterchen
+4  A: 

Yep. Use std::string internally and then just use const char * on the interface functions (which will be converted to std::strings on input.

Peter Alexander
To go a step further, I suggest avoiding any C++ types in your public api function signatures (e.g. no vectors).
Brian
A: 

std::string will work in, at the very least, Visual Studio C++ (and others), so why not just use that?

Ruddy
It won't necessarily work across a DLL boundary, though. Static libraries are problematic, too - even if you compile with the correct compiler version, people who use a non-default STL implementation will get hurt.
peterchen
Good points. Thanks.
Ruddy
A: 

The question is, what your clients will do with that pointer. It should of course be const char*, but if clients will keep and reference it later on, its probably risky to use std::string internally, because as soon as you operate yourself on the strings there is no way to keep std::string from moving memory, as its reference counting mechanism can not work with exported char* pointers. As long as you dont touch the std::string objects, their memory wont move, and the pointer is safe.

RED SOFT ADAIR
A: 

There is no standardized C++ binary interface (at least I haven;t heard about it), thus projects with different settings may appear to be unlinkable together. For example, Visual C++ provides a way to enable/disable iterator debug support. This is controlled by macro and size of some data structures depends on it.

If two codes compiled with different settings start to communicate using these data structures, the best thing you can have is linker error. Other alternatives are worse - stable run-time error, release-configuration-only error, etc...

So if you don't want to restrict your users to single correct project settings set and compiler version, use only primitive data for interface. For internal implementation choose what is more convenient.

maxim1000
A: 

Adding to Poita_'s response:

  • consider unicode support If you ever have to support localization, too, you'll be happy to have done it in the first place

  • when returning char/wchar_t const *, define the lifetime of the data. The best would be to have a project-wide "unless stated otherwise..." standard
    Alternatively, you can return a copy that must be freed through a method exported by your library. (C++ clients can move that into a smart pointer to regain automatic memory management.)

peterchen