Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Char* and QString
Forum Updated to NodeBB v4.3 + New Features

Char* and QString

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 2.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TimS
    wrote on last edited by
    #1

    I know this is a generic question as it could easily apply to std::string or other char wrapper, but can someone tell me what a good approach is for following scenario. All I can see is the need to copy strings and have the client be responsible for deleting the copies.

    Should I use std::string? I'm reading a lot of articles, api code, stack overflow etc and just can't figure out what a 'good' way of doing this is.

    My hesitance in using std::string is mixed messages from what I’ve read about cross boundary compatibility.
    I.e main() is a seperate process from the shared library A+B are in.
    http://stackoverflow.com/questions/2322095/why-does-this-program-crash-passing-of-stdstring-between-dlls
    http://stackoverflow.com/questions/3167560/passing-stdstring-in-a-library-api

    The key here is ease of use for user as well as maximising performance.

    Scenario:

    I'm implementing an API library.
    The external/public functions (free and class members) use char * for all string operations.
    Internal/private implementation classes use QString.

    @
    // a.h
    Class B;
    Class A
    {
    private:
    B* impl;
    public:
    const char* StringData() const;
    }

    // a.cpp
    const char* A::StringData() const
    {
    QString data = impl->StringData();
    xxxxx <- what should I do here for returning a const char * in a safe way
    }

    // b.h
    class B
    {
    QString m_stringData;
    public:
    const QString StringData() const;
    }

    // b.cpp
    const QString B::StringData() const
    {
    return m_stringData;
    }

    // main.cpp

    int main()
    {
    A a;
    const char *stringData = a.StringData(); <- now have a pointer to array that could be deleted anytime, or user has to delete themselves.

    }
    @

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #2

      There is no generic answer for that. As always, it depends. :-)

      First of all, can you guarantee that the libraries and the main are always compiled with the same compiler? Or at least with 100% compatible ones? I ask this, because on Windows, each MSVS version has it's on c-runtime which use different heaps. This also happens in service packs:

      MSVS2005 != MSVS2005 SP1 != MSVS2008 != MSVS2008 SP1 != MSVS2010

      With != means incompatible c-runtime. So if this could happen, you must be memory neutral in the interface (which you might know from older C-APIs and from som Win32 APIs).

      There a solution could be:

      @
      // a.h
      Class B;
      Class A
      {
      private:
      B* impl;
      public:
      int StringData(char* pData, int nLength) const;
      }

      // a.cpp
      int StringData(char* pData, int nLength) const;
      {
      QString data = impl->StringData();

      QByteArray ba = data.toUtf8();          // this depends on the encoding you need
      int nNeededLength = ba.size() + 1;      // I'm not 100% sure whether the endig 0 is part of the byte array... :-(
      if(0 != pData || nLength >= nNeededLength);
      {
          strcpy(pData, ba.constData());     // this depends on the encoding you need
      }
      return nNeededLength;
      

      }

      // main.cpp
      int main()
      {
      A a;
      char* stringData = 0;
      int nLength = a.StringData(0,0);
      if(0 < nLength)
      {
      stringData = new char[nLength];
      a.StringData(stringData, nLength);
      }
      // ...
      }
      @

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TimS
        wrote on last edited by
        #3

        Thanks for quick answer. I figured out part of the ABI issue is differences between implementations and runtimes etc between compilers and versions.

        I don't like users having to pass in a buffer, it's ugly and makes coding painful. Standard for C users, not expected by C++ users in a modern library.

        Perhaps I need to follow the herd and provide a simple wrapped string class in my API?
        I'll always be returning const data so the wrapper should be pretty simple.

        I've been looking at popular C++ libraries and this seems to be common - I can't see any way around returning copies of strings when crossing module boundaries?

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved