Trying to write a textfield value to file in c++ - c++-cli

I am tearing my hair out over this error.
------ Build started: Project: shotfactorybatchgen, Configuration: Debug Win32 ------
shotfactorybatchgen.cpp
c:\documents and settings\administrator\my documents\visual studio 2010\projects\shotfactorybatchgen\shotfactorybatchgen\Form1.h(307): error C2664: 'fprintf' : cannot convert parameter 2 from 'System::String ^' to 'const char *'
No user-defined-conversion operator available, or
Cannot convert a managed type to an unmanaged type
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I have looked all around the interwebs but I can not find an answer. Here is the code that the error is happening in.
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Decimal value;
if(!Decimal::TryParse(textBox4->Text, value)) {
MessageBox::Show("Non-numeric characters detected in 'Wait Time' filed", "Oops", MessageBoxButtons::OK, MessageBoxIcon::Warning);
} else {
if(!Decimal::TryParse(textBox3->Text, value)) {
MessageBox::Show("Non-numeric characters detected in 'Max Upload' filed", "Oops", MessageBoxButtons::OK, MessageBoxIcon::Warning);
} else {
FILE *OutFile = fopen("run.bat","w");
fprintf(OutFile,"#ECHO OFF\r\nC:\\Python26\\python.exe factory.py");
if(factoryname->Text != ""){
fprintf(OutFile," -f ");
fprintf(OutFile,factoryname->Text);
}
fclose(OutFile);
}
}
}
Any ideas? It is a simple windows form application. I am using Visual Studio C++ 2010
Thanks
Colum

If factoryname->Text identifies a property, then its getter may throw a CLR exception, in which case you will leak the file handle OutFile. Consider not using fopen, etc. It's a C library function and there are better alternatives such as std::ofstream.
Alternatively, as you have .NET available, you could use StreamWriter which will let you pass System::String and thus avoid your conversion problem as well:
StreamWriter writer(someFilePath);
writer.WriteLine(someString);
C++/CLI will take care of closing the writer when the scope is exited.

It's simply a conversion error:
cannot convert parameter 2 from 'System::String ^' to 'const char *'
Possible solution is posted here:
What is the best way to convert between char* and System::String in C++/CLI
Opening Files
Convert System::String to const char*

Related

C++/WinRT: CoreApplication::Run(IFrameworkViewSource const&) is throwing E_INVALIDARG

I'm trying to figure out why at this point in the code I'm getting an E_INVALIDARG hresult:
// main.cpp
class App : public implements<App, IFrameworkView>
{
// stuff ...
};
class AppFactory : public implements<AppFactory, IFrameworkViewSource>
{
public:
IFrameworkView CreateView()
{
return make<App>();
}
};
int WINAPI wWinMain(
_In_ HINSTANCE,
_In_ HINSTANCE,
_In_ LPWSTR,
_In_ int)
{
init_apartment();
auto vpf = make<AppFactory>();
CoreApplication::Run(vpf); // <-- throwing E_INVALIDARG somewhere inside CoreApplication::Run
uninit_apartment();
return S_OK;
}
I'd have expected a compile error if I didn't do something required by a class inheriting implements<AppFractory, IFrameworkViewSource>, but as far as I know I'm checking (static) boxes.
fwiw the exception is triggered here:
// Windows.ApplicationModel.Core.h
template <typename D> auto consume_Windows_ApplicationModel_Core_ICoreApplication<D>::Run(winrt::Windows::ApplicationModel::Core::IFrameworkViewSource const& viewSource) const
{
check_hresult(WINRT_IMPL_SHIM(winrt::Windows::ApplicationModel::Core::ICoreApplication)->Run(*(void**)(&viewSource)));
}
The thing inside check_result(...) is what's returning E_INVALIDARG, and subsequently triggering the exception. I'm not a super expert at writing windows applications, largely still in the "copy the template and hope it works while trying to understand something" phase. If there's some kind of tool I should be using to understand what the actual argument I'm passing is that is invalid, I'd appreciate some kind of pointer. I would think if I'm not passing the correct thing here, the strong type check of the argument would trigger a compile error and I'd have an opportunity to address the issue.
Honestly I'm lost here, would appreciate a hint towards where to look to resolve my issue. Thank you.
Update:
Don't know if this is relevant but in the Output tab in VS a line prints out:
Exception thrown at 0x00007FFA6D9A4FD9 (KernelBase.dll) in MyProgram.exe: WinRT originate error - 0x80070057 : 'serverName'.
I have no idea what this is... "serverName"? I don't even see a mention of this in the CoreApplication::Run docs.

no suitable user-defined conversion from System::String ^ to System::String exists

I'm relatively inexperienced with C++ and I'm currently creating a simple Windows Forms project. The following code is providing a strange error that I just can't wrap my head around.
if (folderBrowserDialog1->ShowDialog() == ::DialogResult::OK) {
String filepath = folderBrowserDialog1->SelectedPath;
for (auto& p : std::filesystem::directory_iterator(filepath)) {
// read files from filepath
}
}
The error, "no suitable user-defined conversion from System::String ^ to System::String exists" is referring to the folderBrowserDialog1->SelectedPath line. Despite the docs I've checked stating that SelectedPath is a string, apparently it's not the same type of string as C++ is expecting? I assume I need to do some kind of conversion but I'm at a total loss as to how I should do that as I really assumed that SelectedPath would be a regular String.

(C++ / CLI) Set contents of textbox to content of a .txt

I am looking to set the contents of a textbox to that of a .txt file,
however I cannot get it to work. I have a button which would "refresh" the
content of the textbox to that of the .txt file, here is the code I am using:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
std::ifstream dat1("DataStore.txt");
String^ textHolder;
if (dat1.is_open())
{
while ( getline(dat1, line) )
{
textHolder += line.c_str;
}
textBox1->Text = textHolder;
dat1.close();
}
else textBox1->Text = "Unable to open file";
}
I get these 2 errors when compiling the program:
error C3867: 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': function call missing argument list; use '&std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str' to create a pointer to member
error C2297: '+=' : illegal, right operand has type 'const char *(__thiscall std::basic_string<char,std::char_traits<char>,std::allocator<char>>::* )(void) throw() const'
How do I make this work?
NOTE: I am trying to display the whole .txt file's contents in the textbox
If you are going to use C++/CLI you may as well take advantage of .net. You can use the File class to read the file for you:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
textBox1->Text = System::IO::File::ReadAllText("DataStore.txt");
}
You'll need to hope that the process working directory contains that file. In a GUI app you are better served by specifying full paths to files, since the working directory is typically ill-defined.
If you are trying to learn C++, then perhaps a .net C++/CLI WinForms application is not the place to start.
You forgot to end method c_str, change it to c_str()

visual studio 2012 can't resolve static fields in a dll lib

I'm compiling openexr2.0.0 using visual studio 2012 x64 dll, I got this error:
ImfLut.obj : error LNK2001: unresolved external symbol "private: static union half::uif const * const half::_toFloat" (?_toFloat#half##0QBTuif#1#B)
ImfRgbaYca.obj : error LNK2001: unresolved external symbol "private: static unsigned short const * const half::_eLut" (?_eLut#half##0QBGB)
And I looked up in the half.lib using dumpbin /exports:
Another look up using dumpbin /exports on half.dll:
The two symbols are there. And interestingly, when I remove half.lib from dependency, VS complain convert is also unresolved. This shows that it could find convert but not _toFloat and _eLut. The differences are: _toFloat and _eLut are both static fields, convert is a static method.
class half
{
...
public:
union uif
{
unsigned int i;
float f;
};
private:
HALF_EXPORT static short convert (int i);
HALF_EXPORT static const uif _toFloat[1 << 16];
HALF_EXPORT static const unsigned short _eLut[1 << 9];
...
};
My system is windows 8 x64. Does anyone know how to fix this problem?
You're trying to link against __declspec(dllexport)-ed symbols.
This means you need to make sure you're __declspec(dllimport)-ing those symbols in your project file.
Specifically to half - there's a #define you can add: OPENEXR_DLL that is being checked for appearance in halfExport.h and will do that for you.
Step 14 in the following link solved the problem for me:
https://groups.google.com/forum/#!topic/openvdb-forum/-jFJQ2N4BGc
In your project, add OPENEXR_DLL to "Preprocessor Definitions" in "project properties->C/C++->Preprocessor"

Managed C++, Object reference not set to an instance of an object

I've run into this problem before, but never in a situation like this. I'm completely confused. As the question states, I'm getting the runtime error "Object reference not set to an instance of an object." Using the debugger tools, I think I've pinpointed the problem to this line:
dataFileLocation = path;
The entire function is here:
void DATReader::SetPath(String^ path)
{
if(!File::Exists(path))
{
MessageBox::Show( "DATReader (missing dat file: \n"+path+"\n )", "Error", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
return;
}
dataFileLocation = path;
}
dataFileLocation is declared here, but nothing is assigned to it:
ref class DATReader
{
private:
System::String^ dataFileLocation;
// ...
}
Now I know the reason I'm getting the error is because dataFileLocation is assigned to nothing. But I'm having problems assigning it. When I add = 0; to it, it won't build because its a ref class. When I try to assigned it to = 0; in the constructor, it yells at me for trying to convert it from a System::String^ to an int. If I assign it to a = gcnew String(""); it builds, but throws the same runtime exception.
I don't get it, am I reading the debugger wrong, and this isn't the source of the problem at all? I've just started to use managed code recently, so I'm confused :\
You may want to check and make sure your DATReader object isn't null as well It may be throwing the exception at your DATReader.SetPath() call.
This is a nicety in C# that's missing in C++/CLI. C# generates code that ensures this can never be null. Easily seen in the debugger by setting a breakpoint on the method and inspecting "this". Here's an example program that reproduces the exception:
#include "stdafx.h"
using namespace System;
ref class Example {
String^ dataFileLocation;
public:
void SetPath(String^ path) {
dataFileLocation = path; // Set breakpoint here and inspect "this"
}
};
int main(array<System::String ^> ^args)
{
Example^ obj /* = gcnew Example */;
obj->SetPath("foo");
return 0;
}
Remove the /* */ comments to fix. Fix your code by looking at the call stack to find the method that forgot to instantiate the object.
Managed C++ uses nullptr for null references. So you can check:
if (path == nullptr) { ... }
or use:
if (!String::IsNullOrEmpty(path))