External DLL, string в wchar_t* для возврата в советник

 

Народ, подскажите как привести string в wchar_t* для возврата из DLL.

Три варианта, все возвращают верное значение, только терминал падает незамедлительно после вызова функции.

wchar_t* CharToWChar(const char* text)
{
        size_t size = strlen(text) + 1;
        wchar_t* wa = new wchar_t[size];
        mbstowcs(wa, text, size);
        return wa;
} // CharToWChar

wchar_t* StringToWChar(string s)
{
        wchar_t* wRet = CharToWChar(s.c_str());
        return wRet;

        //wchar_t* wRet = new wchar_t[s.size()];
        //for ( string::size_type i = 0; i < s.size(); ++i ) wRet[i] = s[i];
        //return wRet;

        //int wchars_num = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
        //wchar_t* wstr = new wchar_t[wchars_num];
        //MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, wstr, wchars_num);
        //return wstr;

} // StringToWChar
 

Чтобы вернуть строку, надо создать глобальный объект (строковый буфер) в DLL. Если предполагается работать из нескольких потоков, что нормально для МТ и MQL, то надо синхронизировать обращение к нему. Чтобы во время чтения строки другой вызов не испортил данные.

Такой класс сделал для этого:

#pragma once
#include "Utils.Macros.h"
#include "Utils.EncodeStr.h"
#include "Utils.Single.h"
#include "Utils.Smart.h"
#include "Utils.Synchronize.h"
#include "MT.Macros.h"

//ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ
#define MT_SYNC_TEXT(sText) Utils::PSingleton<MT::SyncText>::GetInstance()->GetText(sText)

namespace MT
 {//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
  // Класс-одиночка осуществляет синхронный доступ к глобальному текстовому буферу для возврата функциями указателя на глобальный буфер с текстом в МТ4.
  //  ПРИМЕР:
  //  EXPFUNC(LPSTR) ServiceReadCmd(const HWND hwndChart)
  //   {
  //    return(MT_SYNC_TEXT(MT_WINDOWS->ReadCmd(hwndChart)));
  //   }
  class SyncText : UTILS_SMART_BASE
   {//==== Переменные. ==================================================================================================================================
    Utils::STRINGBUFA CBufferA;      // Текстовый ANSI-буфер.
    Utils::STRINGBUFW CBufferW;      // Текстовый UNICODE-буфер.
    Utils::Sync::CriticalSection CS; // Класс критической секции.
    //===================================================================================================================================================
    UTILS_PSINGLETON(SyncText); // Синглетон.
    public:
    //===================================================================================================================================================
    // 1.1. Конструктор по умолчанию.
    SyncText() {}
    //---------------------------------------------------------------------------------------------------------------------------------------------------
    // 1.2. Деструктор.
    virtual ~SyncText() {}
    //---------------------------------------------------------------------------------------------------------------------------------------------------
    // 1.3.1. Метод копирует получаемый ANSI-текст в глобальный строковый буфер и возвращает указатель на глобальный строковый буфер.
    //        Обращение к буферу функция синхронизирует.
    LPSTR GetText(const std::string &sText) // Текст для чтения.
     {// Входим в зону защиты инициализации. Защита от одновременных обращений из разных потоков к глобальному буферу.
      LOCK_CS CLock(CS);
      if (sText.empty()) CBufferA.Init();
      else CBufferA.Init(sText);
      return(CBufferA.Pointer<CHAR>());
     }
    //---------------------------------------------------------------------------------------------------------------------------------------------------
    // 1.3.2. Метод копирует получаемый UNICODE-текст в глобальный строковый буфер и возвращает указатель на глобальный строковый буфер.
    //        Обращение к буферу функция синхронизирует.
    LPWSTR GetText(const std::wstring &sText) // Текст для чтения.
     {// Входим в зону защиты инициализации. Защита от одновременных обращений из разных потоков к глобальному буферу.
      LOCK_CS CLock(CS);
      if (sText.empty()) CBufferW.Init();
      else CBufferW.Init(sText);
      return(CBufferW.Pointer<WCHAR>());
     }
    //===================================================================================================================================================
   };
  //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
 }
//ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ

Типа строковый буфер-синглетон. 

 
Спасибо за класс. Работа с критическими секциями реализована у меня верно, и проблема была не в приведении типа string к wchar_t, а в конкатинации длинных строк в одну для возврата. Проблему решил сам, тему можно закрыть.