c# : how to convert c# string to c++ wstring and vice-versa - string

c# code-
string s="おはよう";
I want to send s to c++ dll, as wstring..
how to convert string to wstring in c# ?

A std::wstring is a C++ object, allocated by the C++ runtime and having an implementation-dependent internal format. You might be able to figure out how to create one of those in a C# program and pass it to the unmanaged C++ code, but doing so would be somewhat difficult and fraught with peril. Because the internal structure of a std::wstring is implementation dependent, any change to the C++ compiler or runtime libraries break your solution.
What you're trying to do is typically done by writing an interface layer in C++ that takes an LPTStr parameter, converts it to a std::wstring, and then calls the C++ function that you wanted to call. That is, if the function you want to call is declared as:
int Foo(std::wstring p);
You would write an interface function:
int FooCaller(LPTSTR p)
{
std::wstring str = p;
return Foo(str);
}
And you call FooCaller from your C# program.
In short, C# can't create and pass a std::wstring, so you use a translation layer.

Related

Convert from a LPCTSTR to a wchar*

I have a c++ application, and i need to convert a LPCTSTR to a wchar*.
Is there function to perform this conversion?
Using Visual Studio 2k8.
Thank you
From the comments, you are compiling for Unicode. In which case LPCTSTR evaluates as const wchar_t* and so no conversion is necessary. If you need a modifiable buffer, then you can allocate one and perform a memory copy. That works because the string is already encoded in UTF-16.
Since you are using C++ it makes sense to store strings in string classes rather than using raw C strings. For example you could use std::wstring. Or your could use the MFC/ATL string classes. Exactly which of these options is best for you depends on the specifics of the rest of your code base.
LPCTSTR may either be multibyte or Unicode, determined at compile-time. WinNT.h defines it as follows
#ifdef UNICODE
typedef LPCWSTR LPCTSTR;
#else
typedef LPCSTR LPCTSTR
#endif
meaning that it is already composed of wchar as Rup points out in a comment. So you might want to check UNICODE and use MultiByteToWideChar() if undefined. Of course, you'd need to know the code page the string is using, which depends on where and how it originates. The MultiByteToWideChar documentation has good code samples.

C++/CX - How to convert a number stored as String^ to byte?

I have a C++/CX Windows 8 application and I need to do something similar to the following conversion:
String^ foo = "32";
byte bar = <the numeric value of foo>
How can I convert the number stored within the String^ into the byte type? I am lost without all of the C# magic that I normally use to achieve this!
Thanks in advance for any help on this.
You are getting into trouble by assuming that C++/CX resembles C#. That's not the case at all, it is pure C++ with just some language extensions to make dealing with WinRT types easier. This is not appropriate use of the Platform::String type, it is not a general purpose string class. That's already covered by the standard C++ library. The class was intentionally crippled to discourage the usage you have in mind. This MSDN library article explains it well:
Use the Platform::String Class when you pass strings back and forth to methods in Windows Runtime classes, or when you are interacting with other Windows Runtime components across the application binary interface (ABI) boundary. The Platform::String Class provides methods for several common string operations, but it's not designed to be a full-featured string class. In your C++ module, use standard C++ string types such as wstring for any significant text processing, and then convert the final result to Platform::String^ before you pass it to or from a public interface. It's easy and efficient to convert between wstring or wchar_t* and Platform::String.
So the appropriate code ought to resemble:
#include <string>
...
std::wstring foo(L"32");
auto bar = static_cast<unsigned char>(std::stol(foo));

String^ declaration in C++

As far as I am aware C++ string declaration follows the form:
std::string param;
I was walking through a code and realised the declaration of string is done this way:
System::String^ param;
Can anyone share light on this declaration?! Is this Microsoft Visual C++ string declaration or a special library which provides another alternative to using C++ string.
It's Microsoft-specific, and is part of a language they call C++/CLI. This syntax declares a Common Language Runtime (CLR) String variable (the same kind you get when you declare a string in C#). These are not directly interchangeable with the several C/C++ string types, but Microsoft provides marshalling facilities to convert CLR String objects to unmanaged strings and vice versa.
C++/CLI enables developers to create programs that bridge regular C++ classes/functions (otherwise called "unmanaged code") with CLR classes/functions (otherwise called "managed code"). Microsoft also exposes lower-level features of the CLR to C++/CLI, some that are exposed to C# too (like pointers), and some that aren't (like finer granularity over member access levels).
It's useful if you want to use an existing C or C++ library in a language like C# (by making the bindings in C++/CLI then exposing them to the CLR without going through P/Invokes), or if you want to port an existing unmanaged C/C++ library or application to a managed environment.
This is C++/CLI syntax for a handle to an object on the managed heap.

Which wide-character string structure do I use? CString vs wstring

I have an MFC application in C++ that uses std::string and std::wstring, and frequently casts from one to the other, and a whole lot of other nonsense. I need to standardize everything to a single format, so I was wondering if I should go with CString or std::wstring.
In the application, I'll need to generate strings from a string table, work with a lot of windows calls that require constant tchar or wchar_t pointers, Edit Controls, and interact with a COM object's API that requires BSTR.
I also have vectors of strings, so is there any problem with a vector of CStrings?
Which one is better? What are the pros and cons of each?
Examples
BSTR to wstring
CComBSTR tstr;
wstring album;
if( (trk->get_Info((BSTR *)&tstr)) == S_OK && tstr!= NULL)
album = (wstring)tstr;
wstring to BSTR
CComBSTR tstr = path.c_str();
if(trk->set_Info(tstr) == S_OK)
return true;
String resource to wstring
CString t;
wstring url;
t.LoadString(IDS_SCRIPTURL);
url = t;
GetProfileString() returns a CString.
integer to string format:
wchar_t total[32];
swprintf_s(total, 32, L"%d", trk->getInt());
wstring tot(total);
std::basic_string<> (or rather its specialisations) is horrible to work with, it's imo one of the major shortcomings of the STL (and I'd say C++ in general). It doesn't even know about encodings - c'mon, this is 2010. Being able to define the size of your character isn't enough, 'cause there's no way indicate variable-size characters in a basic_string<>. Now, utf-8 isn't nice to work with with a CString, but it's not as bad as trying to do it with basic_string. While I agree with the spirit of the above posters that a standard solution is better than the alternatives, CString is (if your project uses MFC or ATL anyway) much nicer to work with than std::string/wstring: conversions between ANSI/Unicode (through CStringA and CStringW), BSTR, loading from string table, cast operators to TCHAR (.c_str()? really?), ...
CString also has Format(), which, although not safe and somewhat ugly, is convenient. If you prefer safe formatting libraries, you'll be better off with basic_string.
Furthermore, CString has some algorithms as member functions that you'll need boost string utilities for to do on basic_string such as trim, split etc.
Vectors of CString are no problem.
Guard against a dogmatic dismissal of CString on the basis of it being Windows-only: if you use it in a Windows GUI, the application is Windows-only anyway. That being said, if there's any chance that your code will need to be cross-platform in the future, you're going to be stuck with basic_string<>.
I personally would go with CStrings in this case, since you state that you're working with BSTRs, using COM, and writing this in MFC. While wstrings would be more standards compliant you'll run into issues with constant converting from one to another. Since you're working with COM and writing it in MFC, there's no real reason to worry about making it cross-platform, since no other OS has COM like Windows and MFC is already locking you into Windows.
As you noted, CStrings also have built-in functions to help load strings and convert to BSTRs and the like, all pre-made and already built to work with Windows. So while you need to standardize on one format, why not make it easier to work with?
std::wstring would be much more portable, and benefit from a lot of existing prewritten code in STL and in boost. CString would probably go better with windows API's.
wchat_t : remember that you can get the data out of wstring any time by using the data() function, so you get the needed wchar_t pointer anyway.
BSTR : use SysAllocString to get the BSTR out of a wstring.data().
As for the platform dependance, remember that you can use std::basic_string<T> to define your own string, based on what you want the length of a single character to be.
I'd go for wstring every day....

Passing std::string from VC++2005 to VC++6 DLL results in garbage

I have a dynamic link library written in VC++6. I wrote some code with VC++2005 which calls the native VC++6 library. Whenever I pass std::string to the native library, the result is always garbage. However, this does not happen if I pass other types like char *, int, etc. Any ideal what is causing this?
The following code illustrates this.
// VC++ 6 Code
class __declspec(dllexport) VC6
{
public:
VC6();
void DoSomething(const std::string &s);
}
VC6()::VC6() {}
void VC6::DoSomething(const std::string &s)
{
std::cout << s; // Resulting output on screen is garbage
}
// VC++ 2005 Code
void VC2005::DoSomething()
{
VC6 *vc6 = new VC6();
std::string s("Test String");
vc6->DoSomething(s);
delete vc6;
}
Classes such as std::string aren't necessarily defined the same way in every version of the runtime library (even though they have the same name), so you shouldn't mix the libraries this way. On the other hand, types such as int and char* are the same for a given platform so you can pass them.
In your example, it's better to pass the string as a (pointer,size) pair or simply as a null-terminated string.
Edit: forgot to mention the obvious solution of using the same compiler version. Do this if you want to pass objects around.
Don't do this. It doesn't work.
C++ does not define a fixed ABI, so you can't in general pass non-POD types between libraries or translation units compiled by different compilers.
In your case, VC6 and VC8 have different definitions of std::string (and the compilers may also insert different padding and other changes), and the result is garbage, and/or unpredictable behavior and crashes.
If you need to pass data to a VC6 DLL (a better option might be to recompile that code under a sane compiler), you have to stick to types where you can be sure it'll work. That means 1) POD types (either built-in primitives such as char*, or C structs containing only POD types), or COM objects.
You can write a wrapper DLL with a C interface. A C++/CLI wrapper may be needed if p-invoke alone can not handle the interop. Writing a COM server in ATL is probably a better choice to provide an object oriented interface in native code and to avoid writing another wrapper DLL in C++/CLI).

Resources