станд.:: строка в C#?

OP отправил более полный пример, который показывает проблему:

#include 
#include 
#include 

using namespace std;

int main(){

    initscr();
    setlocale(LC_ALL, "");
    raw();
    keypad(stdscr, TRUE);
    noecho();

    for(int i = 0; i < 10; i++){
        mvaddwstr(0, i, L"\u2550");
    }
    for(int i = 0; i < 6; i++){
        mvaddwstr(1, i, L"\u2550");
    }
    refresh();
    getch();
    endwin();

    return 0;

}

Проблема в том, что библиотека инициализируется с другим языком, чем используется в вызовах mvaddwstr. На странице руководства написано

Библиотека использует локаль, которую инициализировала вызывающая программа. Обычно это делается с помощью setlocale :

setlocale(LC_ALL, "");

Если языковой стандарт не инициализирован, библиотека предполагает, что символы могут быть напечатаны как в ISO-8859-1 , для работы с некоторыми устаревшими программами. Вы должны инициализировать локаль и не полагаться на конкретные детали библиотеки, когда локаль не была настроена.

blockquote>

Поскольку вызов setlocale происходит после initscr , а не раньше, ncurses предполагает, что данные соответствуют ISO-8859-1, и сталкивается с неожиданный сценарий. В других местах, таких как addwstr, ncurses проверяет, являются ли данные действительными wchar_t, но в них используется текущая локаль . В этом случае это далеко от функций, которые, как он знает, должны обрабатываться таким образом (это рендеринг данных, которые уже были обработаны). Сравнение в библиотеке, которое позволяет обрабатывать это с помощью возможности repeat_char , может быть улучшено, но фактическая ошибка в примере программы.

8
задан Ivan Prodanov 17 May 2009 в 12:50
поделиться

3 ответа

std :: string и c # string несовместимы друг с другом. Насколько мне известно, строка C # соответствует передаче char * или wchar_t * в C ++, что касается взаимодействия.
Одна из причин этого заключается в том, что может быть много разных реализаций std :: string, а C # не может предполагать, что вы используете какую-то конкретную.

14
ответ дан 5 December 2019 в 07:36
поделиться

Попробуйте что-то вроде этого:

bool __declspec( dllexport ) OpenA(const TCHAR* pFile)
{ 
   std::string filename(pFile);
   ...
   return true;
}

Вы также должны указать соответствующий набор символов (unicode / ansi) в своем атрибуте DllImport.

В стороне, не имеющей отношения к вашей проблеме сортировки, один обычно передает std: string как константную ссылку: const std: string & filename.

7
ответ дан 5 December 2019 в 07:36
поделиться

Невозможно выполнить маршалинг C ++ std :: string так, как вы пытаетесь. Что вам действительно нужно здесь сделать, так это написать функцию-оболочку, которая использует простой старый const char * и преобразуется в std :: string под капотом.

C ++

extern C { 
  void OpenWrapper(const WCHAR* pName) {
    std::string name = pName;
    OpenA(name);
  }
}

C #

[DllImport("pk2.dll")]
public static extern void OpenWrapper( [In] string name);
1
ответ дан 5 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: