L-префикс для строк в C ++ - PullRequest
       2

L-префикс для строк в C ++

7 голосов
/ 03 ноября 2010

У меня есть статическая библиотека.В этой библиотеке определена следующая функция

int WriteData(LPTSTR s)

Пример вызова функции:

LPTSTR s = (LPTSTR) L"Test Data";   
int n = WriteData(s);

WriteData возвращает 0 при успехе и -1 при ошибке.

Iпишу динамическую 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

Мне нужно вызвать его из приложения ac #.Я предполагаю, что моя подпись DLL-импорта была бы:

        [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 ]

7 голосов
/ 03 ноября 2010

Префикс L делает строку строкой wchar_t.Вы можете использовать функцию Windows API MultiByteToWideChar для преобразования строки ANSI в строку wchar_t.

6 голосов
/ 03 ноября 2010

Конкретной «функцией» для выполнения префикса L является макрос TEXT() или _T().(TEXT определяется Windows SDK, _T является расширением среды выполнения Microsoft C.).

Эти функции автоматически добавляют префикс L, когда ваш проект построен с поддержкой юникода (который используется по умолчанию для новых проектов).теперь в большинстве сред MS Dev) - или не включайте его для проектов, настроенных не на Unicode (или ANSI).

Не выполняйте приведение:

LPTSTR s = (LPTSTR) L"ABC";   // Working fine
     WriteData(s);

Если проект когда-либо был настроендля не Unicode, то L "ABC" все равно будет массивом широких символов, но LPTSTR станет указателем на массив из 8 битных символов.

Вот как правильно назначить строку для Ansi,Юникод, или строка «Текст».(Текст может быть Ansi или Unicode в зависимости от настроек проекта) (Я остановил L, потому что он избыточен, и добавил C, потому что строковые литералы должны быть постоянными).

PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");
1 голос
/ 05 ноября 2010

Попробуйте:

[DllImport("Test.dll")]
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);

Дополнительная информация о маршалинге с помощью атрибута MarshalAs в MSDN .

1 голос
/ 03 ноября 2010

Я думаю, что вы запутались, так как ваша функция должна работать просто отлично:

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");
0 голосов
/ 03 ноября 2010

Я бы обернул твои строки в макрос _T(...). Таким образом, он переносится между сборками ANSI и UNICODE.

Обратите внимание, что вы используете переносимый тип строки - LPTSTR - обратите внимание на T. Он будет меняться между ANSI и UNICODE в зависимости от настроек сборки.

...