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 на основе настроек сборки.