4

We are currently building an API for a certain library. Part of the interface requires the library to get and return to the user classes such as vector and string.

When trying to simulate use of the library in a simple scenario, in debug mode the system crush when delivering a string as an input.

I believe there is a different representation of the string class in debug or release mode. Then our library assumes to receive a certain representation, read a data member incorrectly and crush along the way. So what is the best way method to transferring STL objects in an API. The target OS is windows XP compiled with MSVC 8, although the library user will use windows their compiler might (and probably will) be different Ideas we had so far:

  1. Change string to char* - But then developers might be baffled with the responsibility of releasing the memory.
  2. Use our own version of String – I don't want to develop another private implementation of string.
  3. Release to the user debug version and release version.
  4. Ask people on Stack overflow for some option we miss or don’t understand, or just hear from their experience - done.
Hagai
  • 1,049
  • 11
  • 13
  • 2
    Do you believe there is s different representation or do you know there is? –  Jul 02 '10 at 17:00
  • @Neil: good point. You know more about that? However, even if between release and debug there's no difference, it is still questionable to use STL in an API used by third parties IMHO. – lornova Jul 02 '10 at 17:26
  • And if your library receives the object, which will contain data that must be delivered. Thus, there is no risk of releasing memory data. – lsalamon Jul 02 '10 at 17:31
  • @Neil: I believe. Because if the configuration of the user simulating code is on release, everything works just fine. If you compute sizeof(String) in release and in debug configuration you will get different results. – Hagai Jul 02 '10 at 18:12
  • 1
    You don't explicitly say what OS and toolchain you are using. Everyone is guessing that it's Windows + VisualC++. That's probably because Windows has weird memory management semantics when you start using DLLs, and it also makes "debug" and "release" binaries that are not link-compatible. Unix doesn't usually have these problems - certainly I've written loads of libraries that used STL types in the API and never had a problem. So, perhaps you should just clarify what is your target platform. – alex tingle Jul 02 '10 at 21:39
  • @alex tingle: Thanks, I clarified the issue in the question. – Hagai Jul 03 '10 at 08:07

2 Answers2

7

It's not unreasonable at all to make people link against debug in debug mode, and release in release mode. That is how virtually every library does it. Even huge projects like DirectX release debug compiles of their binaries. #3 is a perfectly reasonable option/solution.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • @Lorenzo: You use the STL of your compiler. If you have a free compiler like GCC, then you make your users update. If you have a paid, more versioned compiler like MSVC, you just compile against MSVC8,9,10. – Puppy Jul 02 '10 at 18:01
  • @DeadMG: but if you compile your library with a given compiler, if you export STL objects you will force the user of the library to use the same environment in its application. – lornova Jul 02 '10 at 21:42
  • @Lorenzo: Libraries aren't compatible between CPUs and such anyway. Once you have the same target, it's not unreasonable to use the same compiler. – Puppy Jul 03 '10 at 10:22
  • @DeadMG: OK, so I'm the library vendor (assume Windows and a DLL) and choose to use Intel C++ 10 compiler and sgi STL. The cutomer will not be aware of what library and compiler I am using, as he will get the binary module. He will use MSVC 7 with the stock STL. My library exports STL string and vectors, are the two implementations compatible? – lornova Jul 03 '10 at 11:35
  • @Lorenzo: That's why you use the majority compiler for your platform. MSVC Express is free. – Puppy Jul 03 '10 at 13:56
6

You should avoid passing STL objects between different binary modules.

For string, you have to rely on const char* for read only parameter and char*, <buffer size> for input parameters...

For vectors, it could be a bit more difficult especially if you have to change the content of the vector...

About your ideas:

  1. You are right, but the convention usually is that you can't store the passed pointer (you have to do your local copy).
  2. At the end you would have the same issue unless you have the same binary representation on debug and release version of your implementation.
  3. This may be harmful if you use different versions/implementation of STL in the two binary modules (unless you are sure that the library user will use the same STL).
lornova
  • 6,667
  • 9
  • 47
  • 74
  • 1
    For down-voters: please add an explanatory comment so we can understand what's wrong... – lornova Jul 02 '10 at 16:57
  • Please explain what you mean by "binary modules". –  Jul 02 '10 at 16:59
  • @Neil: for example an .exe and a .dll, or a statically linked library, or in general any two compiled modules that will be linked together. If they use different implementations of STL... opps. – lornova Jul 02 '10 at 17:00
  • 3
    @lorenzo I pass strings, vectors etc. to static libraries all the time with zero problems. Of course, the libraries must be compiled with the same compiler as the executable, but the same would be true for C code, if the library and executable shared memory management duties. –  Jul 02 '10 at 17:03
  • @Neil: I thought that C (not really sure fore C++) has binary compliance (between different implementations) at linker level when the same calling convention is used. You are almost true about memory management: you can't `free` memory with a C library that was mallocated with another C library, for this reason the operating system allocator is used when designing libraries (at least on Windows). – lornova Jul 02 '10 at 17:09
  • @Lorenzo No, there is no standard for C binary compatibility, though on most platforms there is a default one. And when I design libraries, I don't normally consider the platform, certainly I don't call things like GlobalAlloc(). –  Jul 02 '10 at 17:12
  • 1
    Just to expand on Lorenzo's point a little: you should check that both are using exactly the same debug or non-debug copy of the C runtime DLL. If there's a mismatch or either are static then it's not going to work. – Rup Jul 02 '10 at 17:13
  • @Neil: hmm you're right... the C ABI compatibility is actually enforced by the ABI used by system calls on a specific platforms... – lornova Jul 02 '10 at 17:15
  • @Rup: exactly, however if you are designing a library, you shouldn't force the customer to use a specific STL implementation... – lornova Jul 02 '10 at 17:17
  • 1
    @Lorenzo. Actually, not - the binary ABI is enforced (if that's the word) by the most popular compiler and linker. System calls (on Linux at least) are actually called by invoking a software interrupt. –  Jul 02 '10 at 17:18
  • 1
    @Neil: I don't deal with OS from the sixties :-) Jokes aside, in Windows system calls are C functions, so the calling convention using there is the de facto standard ABI (you can argue that the actual system call is done with a syscall ASM call even on Windows, but the developer is not supposed to deal with that). – lornova Jul 02 '10 at 17:23
  • 1
    @lorenzo UNIX is an OS from the 70s, Windows an OS from the 80s and Linux an OS from the 90s. Also, Windows doesn't really document what is and is not a systems call, which is commonly taken to be a switch into kernel mode. None of this has anything to do with the C ABI, of course. –  Jul 02 '10 at 17:32
  • 1
    @lorenzo If you provide a binary library, you must force the library to use the same (not a specific) Standard Library implementation as the caller. –  Jul 02 '10 at 17:34
  • @Neil: UNIX is from 1969, and Linux is so UNIX-like that can't be considered a 90s design. However it was clearly a joke. – lornova Jul 02 '10 at 19:57
  • @Neil: the documented way to call Windows system services is to use the Windows API, which is a collection of C function. The calling convention of these C functions, plus the alignment requirements, is the de facto standard C ABI in Windows. – lornova Jul 02 '10 at 19:58