So I'm trying to fill a table, which is made by using ListView. "a" is some int, and obviously I can not just add an item like this, cuz it asks for string^. How do I convert my int to this string^? And what's the difference between usual string and string^?
System::Windows::Forms::ListViewItem^ listView1Item;
private: System::Windows::Forms::ListView^ listView1;
...
listView1Item = gcnew Windows::Forms::ListViewItem(a);
listView1->Items->Add(listView1Item);
To convert int a to a string, call a.ToString(). ToString is defined on the .Net base class Object, so just about everything has a ToString you can call. (Since you're in C++/CLI, things that are purely unmanaged will not have a ToString method. But anything that's managed, or primitives that are also used in .Net (e.g., int), will.)
As for the difference between String and String^, I'm not sure exactly what you mean by the "usual string". I'm not sure whether you're referring to C++'s std::string, or to .Net's System::String, just without the ^. String^ refers to the .Net System::String class, as a manged reference. Managed references are roughly equivalent to unmanaged pointers, but the garbage collector is allowed to move things around as it does its work, and the managed reference continues to point at the proper object.
The answer was:
System::Convert::ToString()
Thx everybody for help =)
Related
How to convert System::string^ in to LPCTSTR ?
As my requirement is to clone a file using function CopyFile, it works fine if i give Fix name (OldFile.jpg and LatestFile.jpg) to its parameters (below Code: Works Fine)
LPCTSTR in_f,out_f;
in_f = _T("d:\\Old.jpg");
out_f = _T("d:\\Latest.jpg");
CopyFile(in_f,out_f,false);
above code clone the Old.jpeg in to a Latest.jpg but when i trying to give name (Latest.jpg) which is coming out from some String it won't create file (below Code: NOT Working)
String^ Name = "Latest";
//------Capture Current Date & Time
DateTime datetime = DateTime::Now;
//-------Convert Date Timt in to String
Name = Name + String::Format("{0}",datetime);
Name = Name->Replace('/','-');
Name = Name->Replace(':','-');
Name = Name + ".jpg";
LPCTSTR in_f,out_f;
in_f = _T("d:\\Old.jpg");
out_f = (LPCTSTR)Name; //Trying to Assign Current Latest file Name With date Time here
CopyFile(in_f,out_f,false);
The Problem is CopyFile Took LPCTSTR type as an argument , where as i am giving a type System::string^, So suggest me how to convert this System::string^ in to LPCTSTR so that i can add the current date time with in the name of my file.
I am Using VC++2010 and Windows form Application
Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, or even write the GUI in C++/CLI using WinForms, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. For primary development, it is recommended to use C# with either WinForms or WPF if you want managed code, or C++ with MFC if you want unmanaged.
I'm not sure I agree with Hans's comment that TCHAR is obsolete, but doing an explicit conversion to a wide string and calling CopyFileW is a good option.
Also, one could go the other direction, and convert from unmanaged to managed strings, and use the .Net method to copy files, File::Copy(String^, String^, Boolean).
To convert to a LPCTSTR, I would use marshal_as. Because it's implemented with templates, the compiler will resolve your LPCTSTR to call either the LPCSTR or LPCWSTR version, as appropriate.
Microsoft doesn't have dedicated documentation pages for each templated version of marshal_as, but the Overview of Marshaling in C++ page is a good place to start.
My test program:
#include <msclr\marshal.h>
int main(array<System::String^>^ args)
{
String^ managedStr = "I came from managed land!\r\n";
// This controls the lifetime of the LPCTSTR that marshal_as returns.
// When this goes out of scope, the LPCTSTR will no longer be valid,
// so be aware of its lifetime.
msclr::interop::marshal_context context;
LPCTSTR unmanagedStr = context.marshal_as<LPCTSTR>(managedStr);
OutputDebugString(unmanagedStr);
return 0;
}
Result:
I came from managed land!
You need to append a \0 character at the end of the Name string, since CopyFile() expects zero-terminated strings.
EDIT: As LucasTrzesniewski has pointed out, pinning a .NET string automatically yields a zero-terminated character array. This is documented in the C# specification. See the comments below for more information.
Moreover, you have to "pin" the string in memory, so the garbage collector won't move it around. Then you can create a pointer to the first character of the string. C++/CLI provides some utility types and functions to do this. Here's an example:
pin_ptr<const WCHAR> psName = PtrToStringChars (Name)
PtrToStringChars() is an inline function declared in vcclr.h. psName should be assignable to a LPCTSTR parameter - if not, use a cast. Note that PtrToStringChars() doesn't work if the input string is a nullptr. You need to test explicitly for this case. (However, in your case, Name is certainly not a nullptr).
The String remains pinned until the variable psName gets out of scope. This happens after leaving the { ... } block in which it's declared, e.g. after leaving the current function. No explicit unpinning is needed.
You need to marshaling it to "const char *" and make a static_cast to LPCTSTR.
Take a look at this https://msdn.microsoft.com/en-us/library/bb384865.aspx
I'm working on a C++ Metro style app and have to pass a string by reference (somehow). At first, I passed the String^ which doesn't work because strings are immutable how I have found out.
What would be a proper way to pass a string by reference?
Edit: OK, it seems that it's not that easy since the answers and comments suggest to use return values. But as far as I think this is not applicable in my situation: In this Metro app I have two pages and a string should be "shared" across those two pages.
So in the main page I do this in a click event:
this->Frame->Navigate(newPage, this->TestString);
In the OnNavigatedTo event of the second page I convert the second parameter to a String^ and change it. Then I use this->Frame->GoBack() to navigate back to the first page. There I'd like to have access to the changed string. Unfortunately, GoBack() doesn't allow to pass any parameters as far as I know.
You can use a tracking reference:
void ModifyTheParameter(String^% value) {
value = gcnew String("Blah");
}
That would modify the original variable you passed in as parameter (see MSDN for more info and examples). It would then be used just as any other method taking a String^ parameter.
But if possible, avoid using tracking references as parameters. I'd recommend just returning a String^ and assigning that to the original variable.
Yet another possibility: You could just create some kind of View-agnostic DataModel that contains your String (and possibly other data that you work with). You could then pass that DataModel to your method. Since the DataModel variable isn't changed (just a property of it), you wouldn't need to pass a reference to it.
See below an example of a function f which takes as a parameter a reference to a std::string.
std::string someString;
void f(std::string& s);
f(someString);
I want to add my hashmap into ArrayList in vc++ 08. My code is below.
typedef std::tr1::unordered_map< std::wstring, std::wstring > hashmap;
hashmap numbers;
ArrayList^ myAL = gcnew ArrayList;
myAL->Add(numbers); // gives error...
But it gives error that
error C2664: 'System::Collections::ArrayList::Add' : cannot convert parameter 1 from 'hashmap' to 'System::Object ^'
1> No user-defined-conversion operator available, or
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I tried for cast with object, but not succeeded. Can anyone help me to add hashmap in arraylist?
Thanks in advance...
The operation you're trying above doesn't work because managed and native types don't interoperate directly in that way.
I suggest Kenny Kerr's classic C++/CLI article Best Practices for Writing Efficient and Reliable Code with C++/CLI to figure out your specific interop scenario in more detail, but offhand I think what you want to do is embed a pointer to your native object in a managed object which you'll be able to add to your list structure. If you use Mr. Kerr's AutoPtr class (described in the article above and updated here), you should be able to create a managed class containing the AutoPtr as a member, which you can add to your ArrayList.
This is what I am trying to do:
public void method(int myVal, string myOtherVal)
{
// doing something
}
dynamic myVar = new SomeDynamicObjectImplementer();
method(myVar.IntProperty, myVar.StringProperty);
Note that my properties are also DynamicObjects. My problem is that the TryConvert method is never called and that I get a runtime error saying the method signature is invalid.
The following is working great:
string strVar = myVar.StringProperty;
int intVar = myVar.IntProperty;
And I would like to avoid
method((int)myVar.IntProperty, (string)myVar.StringProperty);
Is it possible to override something in DynamicObject to allow this? (or something else)
Thank you
The problem is your assumption that it will try a dynamic implicit convert on arguments of an dynamic invocation to make a method call work, this is not true.
When your arguments aren't statically typed, it will use the runtime type to find the best matching method (if the runtime type matches the static rules for implicit conversion to the argument type this will work too), since your your IntProperty,StringProperty seem to be returning a DynamicObject rather than an Int and a String or something that could statically be converter implicitly, this lookup will fail.
If SomeDynamicObjectImplementer could actually return an Int for IntProperty and a String for StringProperty your method call for without casting would actually work. It's also probably a better dynamic typing practice if you data type is based on the actually type of data rather than usage using try convert. You could add actually implicit convert methods for every possible type that you could return to that returned DynamicObject type, but that could cause strange resolution issues to depending on how much you are overloading.
However, another option to keep your dynamic implementation the same is to mix a little controlled static typing in, you can use ImpromputInterface (in nuget) to put an interface on top of a dynamic object, if you do that then the TryConvert method would be called on your returned DynamicObjects.
public interface ISomeStaticInterface{
int IntProperty {get;}
string StringProperty {get;}
}
...
var myVar = new SomeDynamicObjectImplementer().ActLike<ISomeStaticInterface>();
method(myVar.IntProperty, myVar.StringProperty);
Instead of using myVar.IntProperty can't you just put them in variables first, like you already did, and then use then for your method?
so method(intVar , strVar); seems fine. At least more elegant than casting.
Of course, if you're already certain your object will have IntProperty and StringProperty, why not just make an actual object with those properties instead?
Why are you doing the cast?
method(myVar.IntProperty, myVar.StringProperty);
should compile.
If the two properties must be the types suggested by the names then they shouldn't be dynamic.
I know that
detachNewThreadSelector:toTarget:withObject
can have a (id)anArgument. I have searched it that it can work for NSString.
However, when I pass an integer or size_t, it crashed. Can somebody tell me what is (id)anArgument?
What's more, how can I pass more than one parameter to the thread? For example, I have a function,
-(NSInteger)getIneger: (NSInteger) pageNumber withName(NSString*) filename ;
something like that.
Thanks
What (id)anArgument tells you is that you need to pass an Objective-C argument. Since neither integer nor size_t are Objective-C objects, the application crashes. You will need to package them within an NSNumber for this to work. You will also have to alter the method to take in an NSNumber rather than the int. To pass two or more arguments, I suggest you use an NSDictionary object to pass values based on keys. You can define a method that takes in an NSDictionary object, unpacks the values and calls the original method you had intended to call.