L префикс для строк в C++
у меня есть статическая библиотека. Эта библиотека имеет следующую функцию, определенную
int WriteData(LPTSTR s)
образец для вызова функции -
LPTSTR s = (LPTSTR) L"Test Data";
int n = WriteData(s);
WriteData возвращает 0 при успехе и -1 при сбое.
Я пишу динамическую DLL для экспорта этой функции.
int TestFun(LPTSTR lpData)
{
return WriteData(lpData);
}
результат тестирования приложения на C++
LPTSTR s = (LPTSTR) L"Test Data";
TestFun(s); //OK return 0
LPTSTR s = (LPTSTR) "Test Data";
TestFun(s); //Fail return -1
Я должен вызвать его из приложения c#. Я предполагаю, что моя подпись DLL-Import будет:
[DllImport("Test.dll")]
private static extern int TestFun(String s);
мой вопрос очень прост, как я могу назвать его из .Net? Как вы можете видеть у меня есть контроль над
TestFun(LPTSTR lpData)
но нет контроля над
WriteData(LPTSTR s)
спасибо всем за их вклад. Пока я застрял на кастинге. Я думаю, что моя проблема будет решена, когда я смогу взять ввод от пользователя и написать 2 строки для литья вместо следующей строки.
LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and
TestFun(s); //OK return 0
5 ответов
префикс L делает строку строкой wchar_t.
Вы можете использовать функцию Windows API MultiByteToWideChar
для преобразования строки ANSI в строку wchar_t.
конкретная "функция" для выполнения префикса L-это макрос TEXT()
или _T()
. (Текст определяется Windows SDK, _T является расширением среды выполнения Microsoft C).
эти функции автоматически добавляют префикс L, когда ваш проект построен с поддержкой unicode on (который по умолчанию используется для новых проектов в большинстве сред MS Dev) - или оставляют его для проектов, не настроенных unicode (или ansi).
Не делайте этого в ролях:
LPTSTR s = (LPTSTR) L"ABC"; // Working fine
WriteData(s);
если проект был когда-либо настроен для не Unicode, тогда L"ABC" все равно будет массивом широких символов, но LPTSTR станет указателем на массив 8-битных символов.
вот как правильно назначить строку Ansi, Unicode или" текстовой " строке. (Текст может быть Ansi или Unicode в зависимости от настроек проекта) (я оставил L, потому что он избыточен, и добавил C, потому что строковые литералы должны быть постоянными).
PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");
Я думаю, что вы смущены, так как ваша функция должна работать нормально:
int TestFun(LPTSTR lpData)
{
return WriteData(lpData); // Should be happy
}
но когда вызов ваша функция, вы должны быть осторожны:
TestFun((LPTSTR) L"ABC"); // Will work fine
TestFun((LPTSTR) "ABC"); // Will not work
это потому, что" ABC"и L" ABC " - это две разные вещи. Если вы посмотрите на них в памяти:
"ABC" | 65 66 67 00
L"ABC" | 65 00 66 00 67 00 00 00
редактировать, чтобы добавить:
нет ничего похожего на префикс L в .Net
это просто неправильно. Я только что открыл "Новый проект - >C++->консоль CLR" в VisualStudio, и первая строка:
Console::WriteLine(L"Hello World");
попробуй:
[DllImport("Test.dll")]
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);
дополнительная информация о маршалинге с помощью MarshalAsAttribute on MSDN.
Я бы обернул ваши струны в _T(...)
макрос. Таким образом, его перенос между сборками ANSI и UNICODE.
обратите внимание, что вы используете портативный тип String - LPTSTR
- обратите внимание на T
. Он будет меняться между ANSI и UNICODE на основе настроек сборки.