Я понял, как заставить текст правильно отображаться в форме .net. Это на самом деле не имеет ничего общего со шрифтом и больше связано с преобразованием данных для .net. Я изменил код, который был в основном так:
string Name = reader.GetString(column);
до
string Name = System.Text.Encoding.Default.GetString(reader.GetOracleString(column).GetNonUnicodeBytes());
Мне все равно придется убедиться, что это не вызывает проблем ни с одним из других языков, которые клиенты используют нормально, но пока он хорошо выглядит с греческим и английским языками.
Теперь мне нужно отменить этот процесс при добавлении параметра OracleCommand для сохранения. Оригинальный код выглядел примерно так:
cmd.Parameters.Add(new OracleParameter(":name", Name));
что экономит мусор. Значение строки «Имя» выглядит нормально. Неуправляемый код C ++, который работает, просто собирает SQL-оператор в массив символов (греческий текст всегда также обрабатывается в массиве char) и выполняет его с помощью вызова функции OCI (API Oracle). Код .net использует ODAC (клиент доступа к данным Oracle) для доступа к базе данных.
ОБНОВЛЕНИЕ:
Я решил вторую часть своей проблемы (сохранение) и узнал больше о том, что происходит.
Данные, поступающие в .net из Oracle, выглядят так в памяти, когда я помещаю их в строковый тип данных .net без каких-либо преобразований:
00 0a 33 79 07 00 00 00 06 00 00 00 d4 00 e1 00 ec 00 e5 00 df 00 ef 00 00 00 00 00 00 00 00 00 00 00 00 00 .. 3y ........ Τ .α.μ.ε.ί.ο ............
Эта строка некорректно отображается в .net как:
Ôáìåßï
Содержимое памяти строки .net после преобразования (код преобразования показан выше):
00 0a 33 79 07 00 00 00 06 00 00 00 a4 03 b1 03 до н.э. 03 b5 03 af 03 bf 03 00 00 00 00 00 00 00 00 00 00 00 ..3y ........ ¤. ±. Μ.µ .―. Ώ ............
Вы можете видеть, что для каждого символа 3 берется из старшего куска младшего байта и помещается в старший байт.
Строка теперь правильно отображается в .net как:
Ταμείο
Как показывает информация выше, кажется, что .net представляет символы не так, как неуправляемые C ++ и Oracle. Я сделал несколько тестов и обнаружил, что точка разрыва 160 (шестнадцатеричное значение a0). Поэтому при использовании значений символов от 0 до 159 (от 00 до 9f) нет никакой разницы. Как только будет использовано значение 160 или выше, будет разница.
Мое решение будет работать только для значений символов от 0 до 255, потому что я сбрасываю старший байт символа в моих преобразованиях. Это должно работать для нашего приложения, так как мы никогда не поддерживали многобайтовые наборы символов.
Упрощенная версия того, что я делаю, чтобы преобразовать строку обратно в формат для сохранения в Oracle:
//"name" represents a .net string data type containing the data to save
char[] textChars = new char[4000]; //4000 is the max varchar2 column size in Oracle
byte[] textBytes;
int index = 0;
textBytes = (System.Text.Encoding.Default.GetBytes((name).ToCharArray()));
foreach (byte textByte in textBytes)
{
textChars[index++] = (char)textByte;
}
string textString = new string(textChars, 0, index);
cmd.Parameters.Add(new OracleParameter(":name", (object)(textString)));
Вся эта штука такая хакерская - если у кого-то есть способ получше, поделитесь им. Кажется, должен быть какой-то простой способ решения всей этой проблемы.