问题
I have a static library. This library have the following function defined
int WriteData(LPTSTR s)
The sample to call the function is
LPTSTR s = (LPTSTR) L"Test Data";
int n = WriteData(s);
WriteData return 0 on success and -1 on failure.
I am writing a dynamic DLL to export this function.
int TestFun(LPTSTR lpData)
{
return WriteData(lpData);
}
A C++ test application result
LPTSTR s = (LPTSTR) L"Test Data";
TestFun(s); //OK return 0
LPTSTR s = (LPTSTR) "Test Data";
TestFun(s); //Fail return -1
I have to call it from a c# application. I assume my DLL-Import signature would be:
[DllImport("Test.dll")]
private static extern int TestFun(String s);
My question is very simple How can i call it from .Net? As you can see i have control over
TestFun(LPTSTR lpData)
but no control over
WriteData(LPTSTR s)
Thanks everybody for their input. So far i am stuck on casting. I think my problem would be solved when i woul be able take input from user and write 2 line for casting in place of following line.
LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and
TestFun(s); //OK return 0
回答1:
The L prefix makes the string a wchar_t string.
You can use the Windows API function MultiByteToWideChar
to convert an ANSI string to a wchar_t string.
回答2:
The specific "function" to perform the L prefix is a macro TEXT()
or _T()
. (TEXT is defined by the Windows SDK, _T is an extension of the Microsoft C Runtime).
These functions automatically add the L prefix when your project is built with unicode support on (which is the default for new projects now in most MS Dev environments) - or leave it off for non unicode (or ansi) configured projects.
Don't do this cast:
LPTSTR s = (LPTSTR) L"ABC"; // Working fine
WriteData(s);
If the project was ever configured for non Unicode, then L"ABC" would still be an array of wide-characters, but LPTSTR would become a pointer to an array of 8bit characters.
This is how to correctly assign a string to an Ansi, Unicode, or "Text" string. (Text can be Ansi or Unicode depending on project settings) (I left off the L because its redundant, and added a C, because string literals should be constant).
PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");
回答3:
I think you're confused, as your function should work just fine:
int TestFun(LPTSTR lpData)
{
return WriteData(lpData); // Should be happy
}
But when you call your function, you'll have to be careful:
TestFun((LPTSTR) L"ABC"); // Will work fine
TestFun((LPTSTR) "ABC"); // Will not work
This is because "ABC" and L"ABC" are two different things. If you look at them in memory:
"ABC" | 65 66 67 00
L"ABC" | 65 00 66 00 67 00 00 00
Edited to add:
There is nothing like L prefix in .Net
This is just wrong. I just opened "New Project->C++->CLR Console" in VisualStudio, and the first line is:
Console::WriteLine(L"Hello World");
回答4:
Try:
[DllImport("Test.dll")]
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);
More information on marshaling with the MarshalAsAttribute on MSDN.
回答5:
I would wrap your strings in the _T(...)
macro. That way its portable between ANSI and UNICODE builds.
Note that you are using the portable string type - LPTSTR
- note the T
. It will change between ANSI and UNICODE based on build settings.
来源:https://stackoverflow.com/questions/4086817/l-prefix-for-strings-in-c