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
, может быть улучшено, но фактическая ошибка в примере программы.
std :: string и c # string несовместимы друг с другом. Насколько мне известно, строка C # соответствует передаче char *
или wchar_t *
в C ++, что касается взаимодействия.
Одна из причин этого заключается в том, что может быть много разных реализаций std :: string, а C # не может предполагать, что вы используете какую-то конкретную.
Попробуйте что-то вроде этого:
bool __declspec( dllexport ) OpenA(const TCHAR* pFile)
{
std::string filename(pFile);
...
return true;
}
Вы также должны указать соответствующий набор символов (unicode / ansi) в своем атрибуте DllImport.
В стороне, не имеющей отношения к вашей проблеме сортировки, один обычно передает std: string как константную ссылку: const std: string & filename.
Невозможно выполнить маршалинг 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);