Unable to get the end of file using StreamReader - c++-cli

I'm getting the next error using this code: (System.IndexOutOfRangeException)
int main(array<System::String ^> ^args)
{
String^ str="C:\\somefile.txt";
StreamReader^ sr=gcnew StreamReader(str);
String^ mystr=sr->ReadToEnd();
int i=0;
while (mystr[i++]!='\0') //what's wrong wth this check?
{
Console::Write(mystr[i]);
}
}

Nothing says that the string in a String class has to be zero-terminated like an old C-style string. Instead you should be getting the length from the string object itself.

Related

Please fix my program error i m stuck

i am using visual C++ 2010 i m having just one error i want user to enter inputs model and color and then it will pass to a public variable and public member function will access private data members and assign values to it then a public member function will display those values main.when i try to write s1.colr[10] to pass it to fuunction it gives error.
include
using namespace std;
#include<conio.h>
class vehicle
{
private:
int d;
char color[10];
public:
int mdl;
char colr[10];
void get_input(int a,char b[10])
{
d=a ;
color[10]=b[10];
}
void disp()
{
cout<<"Model Number Is:"<<d ;
cout<<"Color Is:"<<color[10];
}
};
int main()
{
vehicle s1;
cout<<"Enter Model Number:";
cin>>s1.mdl;
cout<<"Enter Color:";
cin>>s1.colr[10];
s1.get_input(s1.mdl,s1.colr[10]);
s1.disp();
getch();
}
Use s1.colr insterad of so.colr[10]
cin>>s1.colr[10];
s1.get_input(s1.mdl,s1.colr[10]);
and you code will compile.
Don't use conio.h, #inlude <iostream>.
Live on coliru

Simple convert C++/CLI int^ to unmanaged int*

This is so basic it should be easy to find. In my searches all I get is more complex solutions. Converting strings, marshaling, pinning objects. How do you simply convert from a c++/CLI int^ pointer to a native int* in C++/CLI.
The body of my function is
void Open(int ^Hndl)
{
void Unmanaged_Open(Hndl); // How do you pass the pointer to this
}
where
void Unmanaged_Open(int *handle);
Here is how you implement an output parameter in C++/CLI, like C#'s void func(out int x). Note that there is no int^.
void Open([OutAttribute] int% retval)
{
int result;
if (!UnmanagedOpen(&result))
throw gcnew Exception("Open failed!");
retval = result;
}
Note that it is probably even better to simply return the value. Out parameters most appear in native functions when the return value is used for error checking. You can either use exceptions in .NET for error-checking, like so:
int Open()
{
int result;
if (!UnmanagedOpen(&result))
throw gcnew Exception("Open failed!");
return result;
}
or if failure is expected (untrusted input, for example), implement the TryXYZ pattern (described on MSDN):
bool TryOpen([OutAttribute] int% retval)
{
retval = 0;
int result;
if (!UnmanagedOpen(&result)) return false;
retval = result;
return true;
}

Type casting in C++\CLI project

I have project which I am compiling with /clr. I have a class like below..
ref class A
{
public:
void CheckValue(void * test);
typedef ref struct val
{
std::string *x;
}val_t;
};
in my implementation I ahve to use something like below..
void A::CheckValue(void *test)
{
a::val_t^ allVal = (a::val_t^)test;
}
in my main I have used like..
int main()
{
A^ obj = gcnew A();
a::val_t valObj = new std::string("Test");
obj->CheckValue((void*)valObj);
}
I am getting type cast error and two places -
obj->CheckValue((void*)valObj);
and at
obj->CheckValue((void*)valObj);
error C2440: 'type cast' : cannot convert from 'void*' to 'A::val_t ^'
This snippet is just to show behavior at my end and I ahve to use it this way only. Earlier I was running it using non /clr so it compiled fine.
Now question I have how can I make this type casting work in C++/CLI type project?
Replace void * with Object^. You can also write a generic version of CheckValue but then there is not much point of having a weak-typed parameter when you have the type in the generic parameter.
A reference handle represents an object on the managed heap. Unlike a native pointer, CLR could move the object around during a function call, so the behavior of a pointer and a reference handle is different, and a type cast would fail. You can also pin the object being referenced using pin_ptr if you really need a void* so CLR would not be moving the object during the function call.
Here is how I would get around the limitation you are seeing, just remove the struct from the managed object, since it contains native pointer types.
struct val_t
{
char* x;
};
ref class A
{
public:
void CheckValue(void* test);
};
void A::CheckValue(void* test)
{
val_t* allVal = (val_t*)test;
}
int main()
{
A^ obj = gcnew A();
val_t valObj;
valObj.x = "Test";
obj->CheckValue((void*)&valObj);
}
Now, if you absolutely need the struct to be managed, here is how to do it:
ref class A
{
public:
void CheckValue(void * test);
value struct val_t
{
char* x;
};
};
void A::CheckValue(void *test)
{
a::val_t* allVal = (a::val_t*)test;
}
int main()
{
A^ obj = gcnew A();
a::val_t valObj;
valObj.x = "Test";
pin_ptr<a::val_t> valPin = &valObj;
obj->CheckValue((void*)valPin);
}

JNA - output parameter in DLL

How can I get the output parameter, which is in a method in a C++ DLL?
public class MyClass {
public int error = 0;
public String MyMethod(){
String str = null;
error = error(str);
if (error == 0){
return str;
}
else
return null;
}
public native int error(String outputparam);
static {
Native.register("MyDLL");
}
}
See this JNA FAQ entry, which explains how to extract a "returned" string from a buffer used as a parameter.

converting System::String^ to std::string inside ref class member

I'm trying to write a wrapper for a very simple std::pair<std::string, float> in C++/CLI but I get the error message: no instance of constructor "std::pair<_Ty1, _Ty2>::pair [with _Ty1=std::string, _Ty2=float]" matches the argument list, argument types are: (std::string, float)
What am I doing wrong and why doesn't std::string match std::string?
#include <msclr\marshal_cppstd.h>
#include <string>
using namespace System;
using namespace System::Runtime::InteropServices;
typedef std::pair<std::string, float> Parameter;
static std::string StringToNative(String^ str)
{
msclr::interop::marshal_context context;
return context.marshal_as<std::string>(str);;
}
public ref class CLIParameter
{
public:
CLIParameter(System::String^ name, float value) : _name(name), _value(value) {};
Parameter toNativeParameter()
{
return Parameter(StringToNative(_name), _value);
}
private:
System::String^ _name;
float _value;
};
int main()
{
CLIParameter^ par = gcnew CLIParameter("test", 1);
}
Your method toNativeParameter() is incorrect. It should be defined as follows:
Parameter toNativeParameter()
{
// copy the floating point value from the managed heap to the local stack
float value = _value;
// create the pair
return std::make_pair(StringToNative(_name), value);
}
Notice that you should use std::make_pair to create the actual pair. In addition, a key step to make this work is copying the floating point value from the managed heap into the local stack. The reason is that native functions such as std::make_pair cannot create native references to an object from the managed (garbage collected) heap i.e. a member of a managed class.