Archived

This forum has been archived. Please start a new discussion on GitHub.

Can't use wstring

Hello!

I have a Qt-based Ice Client and Server. Client reads a file to QString. File contains the Russian text, therefore I can't use std::string (it doesn't support unicode). So, there is a following task: send to server this string without contents damage. I tried two ways.
  1. Change mapping from string to wstring:
    module Server
    {
            interface AbstractServer
            {
                    ["cpp:type:wstring"]string get(string from);
                    void put(string to, ["cpp:type:wstring"]string content);
            };
    };
    
    And I got following link errors:
    abstractserver.obj:-1: error: LNK2019: unresolved external symbol reference "__declspec(dllimport) public: void __thiscall IceInternal::BasicStream::write(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > const &)" (__imp_?write@BasicStream@IceInternal@@QAEXABV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z) &#1074; &#1092;&#1091;&#1085;&#1082;&#1094;&#1080;&#1080; "private: class IceInternal::Handle<class Ice::AsyncResult> __thiscall IceProxy::Server::AbstractServer::begin_get(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > const &,class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > > const *,class IceUtil::Handle<class IceInternal::CallbackBase> const &,class IceInternal::Handle<class Ice::LocalObject> const &)" (?begin_get@AbstractServer@Server@IceProxy@@AAE?AV?$Handle@VAsyncResult@Ice@@@IceInternal@@ABV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@PBV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@@2@@7@ABV?$Handle@VCallbackBase@IceInternal@@@IceUtil@@ABV?$Handle@VLocalObject@Ice@@@5@@Z)
    
    abstractserver.obj:-1: error: LNK2019: unresolved external symbol reference "__declspec(dllimport) public: void __thiscall IceInternal::BasicStream::read(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > &)" (__imp_?read@BasicStream@IceInternal@@QAEXAAV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z) &#1074; &#1092;&#1091;&#1085;&#1082;&#1094;&#1080;&#1080; __catch$?end_get@AbstractServer@Server@IceProxy@@QAE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@ABV?$Handle@VAsyncResult@Ice@@@IceInternal@@@Z$0
    
  2. I removed string to wstring mapping and tried to use IceUtil functions. I wrote the following code:
    #include <IceUtil/Unicode.h>
    std::wstring wstr = // here the Russian text gotten from the file
    std::string str = IceUtil::wstringToString(wstr);
    
    But at linking I again get an error that the symbol can't be found:
    main.obj:-1: error: LNK2019: unresolved symbol reference "__declspec(dllimport) class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl IceUtil::wstringToString(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > const &,enum IceUtil::ConversionFlags)" (__imp_?wstringToString@IceUtil@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@3@W4ConversionFlags@1@@Z) in function _main
    
    It seems wstring like string. Without this code, it works well.

How I can resolve this problem?

Comments

  • xdm
    xdm La Coruña, Spain
    Can you show us the complete compile and link commands, with the output of both.

    Note that to send unicode data with Ice you don't need to use wstring, you can use string with UTF-8 encoded data, for example as returned by QString.toUtf8().data()
  • Oh, thank you, Jose! It works with Utf8. I tried to convert QString to Utf8 at the client-side before, but I forgot about converting to Utf8 at the server-side and used toStdString convertion. Now I use the following code:

    Client-side
    void IceClient::get( const QString& file, QIODevice* dev )
    {
        std::string content;
        try
        {
            content = server_->get( file.toStdString() );
        }
        catch ( const Ice::Exception& e )
        {
            error_ = HostNotFound;
            errorString_ = tr("Cannot get file from ICE-server, probably it was crashed.\n");
            state_ = Unconnected;
            emit stateChanged( Unconnected );
            return;
        }
    
        QTextStream stream( dev );
        stream << QString::fromUtf8(content);
        emit done( false );
    
        state_ = Connected;
        emit stateChanged( Connected );
    }
    
    Server-side
    std::string IceServer::get( const std::string& from, const Ice::Current& )	// ~send_to_client
    {
        QFile file( QString::fromStdString(from) );
        if( !file.open( QIODevice::ReadOnly ) )
        {
                emit error( "Cannot find file on server to read data" );
                state_ = Waiting;
                emit stateChanged( Waiting );
                return std::string();
        }
    
        QTextStream stream(&file);
        std::string content = stream.readAll().toUtf8().data();
        emit done();
    
        state_ = Waiting;
        emit stateChanged( Waiting );
    
        file.close();
        return content;
    }