Visual C++ Write BSTR to File - string

I am a newbie to C++.
I am trying to write a BSTR to a CSV file, but the data when I print with wcout is not matching with data what's present in file.
BSTR tempString;
ofstream outputFile;
outputFile.open("C:\\data.csv",ios::out);
tempString = getData();
outputFile.write(tempString);
outputFile.close();
BSTR getData()
{
BSTR KBIDValue;
IStringCollection *KBID;
KBID->get_Item(0,&KBIDValue);
return KBIDValue;
}
If tempString = L"TestData" -> I am able to see the same value in
file.
If tempString = getData(); where the function returns a BSTR,
I am not able to see same value in file.
Could some please clarify this? Also please explain what exactly is the method to write BSTR to file?
EDIT: Added code

You are not returning anything!!!
BSTR getData()
{
BSTR KBIDValue;
IStringCollection *KBID;
KBID->get_Item(0,&KBIDValue);
return KBIDValue;
}
However if you want to convert to some other form and print, look here

I have added the following lines of code in my program and giving the results correctly.
ofstream outputFile;
outputFile.open(filePath,ios::out);
outputFile << W2A(CString(tempString));

Related

run an EXE file and receive return value from it using VC++

Please i want to creat a program/function in VC++ that allow me to run an EXE file and receive return value from it.
My EXE file tht i want to run is a console Application, it need two argument Arg1 (String) and Arg2 (Float), and return an OutPut (Float).
Something like :
OutPut = MyEXEFile.exe Arg1 Arg2
Command-line arguments come in only one data type: array of C-style string.
Input and output come in only one data type: stream of bytes.
You can supply any command-line and redirection the output if you use CreateProcess from the <windows.h> header file. Other data types such as float will need to be handled the same way you would handle them in a data file.
Here is an example on MSDN: Creating a Child Process with Redirected Input and Output
I find the solution, this is work fine for me, i test it, and it work well.
This is the link of the page where i find the solution, i fixe some errors, and now it ready for implement.
http://www.codeproject.com/Articles/10134/Execute-a-Console-Application-From-VC?fid=172409&fr=26#xx0xx
This is the exemple we need to execute. PS: this line is not a part of the our program, it's just here to explain the algorithm:
MyEXEFile.exe Arg1 Arg2 > sResult
The "MyEXEFile.exe" take two arguments (Arg1 and Arg2) and return a value in the sResult Variable.
Let us program this exemple with Visual C++ using CreatProcess :
CString ExePath="C:\\MyEXEFile.exe";
CString arg1="2";
CString arg2="3";
CString sResult="";
CString strCommandLine = ExePath + " " + arg1 + " " + arg2;
// Call the ExecuteExternalFile function
sResult = ExecuteExternalFile(strCommandLine);
This is the Function who will read the output of MyEXEFile.exe File :
CString ExecuteExternalFile(CString csExecute)
{
SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr,sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
HANDLE rPipe, wPipe;
//Create pipes to write and read data
CreatePipe(&rPipe,&wPipe,&secattr,0);
//
STARTUPINFO sInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo,sizeof(pInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESTDHANDLES;
sInfo.hStdInput=NULL;
sInfo.hStdOutput=wPipe;
sInfo.hStdError=wPipe;
char command[1024];
strcpy(command,csExecute.GetBuffer(csExecute.GetLength()));
//Create the process here.
CreateProcess(0,command,0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
CloseHandle(wPipe);
//now read the output pipe here.
char buf[100];
DWORD reDword;
CString m_csOutput,csTemp;
BOOL res;
do
{
res=::ReadFile(rPipe,buf,100,&reDword,0);
csTemp=buf;
m_csOutput+=csTemp.Left(reDword);
}while(res);
CloseHandle( pInfo.hProcess );
CloseHandle( pInfo.hThread );
return m_csOutput;
}
Creating a Child Process with Redirected Input and Output
You are going overkill.
For a command line app, the system command will do what you are looking for.
int status = system("MyEXEFile.exe Arg1 Arg2");

C++ Convert Sytem::String^ to LPCOLESTR

I write in mixed mode (C++/CLI) and I can not resolve this problem:
String ^progID = "Matrikon.OPC.Server";
CLSID clsid;
HRESULT result = CLSIDFromProgID(progID, &clsid);
error C2664: 'CLSIDFromProgID' : cannot convert parameter 1 from 'System::String ^' to 'LPCOLESTR'
How can I convert String^ to LPCOLESTR ?
Thanks!
I made another way:
// 1.
pin_ptr<const WCHAR> str = PtrToStringChars(progID);
LPCOLESTR coleString = (LPWSTR)str;
I have found that pin_ptr will be released if goes out of scope Define the Scope of Pinning Pointers and pin_ptr (C++/CLI)
This code works well for me:
// 2. this is the same like (1.)
String ^progID2 = "Matrikon.OPC.Simulation.1";// This is example of dynamic string
pin_ptr<const WCHAR> PINprogID2 = PtrToStringChars(progID2);
CLSID clsid2;
HRESULT result2 = CLSIDFromProgID(PINprogID2, &clsid2); //(LPCOLESTR, &CLSID)
Another example:
// 3.
pin_ptr<const WCHAR> sclsid3 = PtrToStringChars("{63D5F432-CFE4-11d1-B2C8-0060083BA1FB}");
CLSID clsid3;
CLSIDFromString((WCHAR*)sclsid3, &clsid3); //(LPOLESTR, &CLSID)
I am not much experienced and I am not sure if there are some lack of memory, but I think those codes are correct.
Avoid using the hammer for every nail. C++/CLI lets you just as easily use native types. So it is simply:
LPCOLESTR progid = L"Matrikon.OPC.Server";
// etc..
Non-zero odds (always say why) that you can simply use Type::GetTypeFromProgID().
First, lets convert System::String to char*
IntPtr p = Marshal::StringToHGlobalAnsi(progID);
char *pNewCharStr = static_cast<char*>(p.ToPointer());
second, casting char * to LPCOLESTR using ATL conversion macro:
LPCOLESTR converted_string = A2COLE(pNewCharStr);

How to convert string to LPSTR in WinAPI function which stores output in string

I am trying to store some contents into a string variable by passing it as a parameter in various types of Windows API functions which accepts variable like char *.
For example, my code is:-
std::string myString;
GetCurrentDirectoryA( MAX_PATH, myString );
Now how do I convert the string variable to LPSTR in this case.
Please see, this function is not meant for passing the contents of string as input, but the function stores some contents into string variable after execution. So, myString.c_str( ) is ruled out.
Edit: I have a workaround solution of removing the concept of string and replacing it with something like
char myString[ MAX_PATH ];
but that is not my objective. I want to make use of string. Is there any way possible?
Also casting like
GetCurrentDirectoryA( MAX_PATH, ( LPSTR ) myString );
is not working.
Thanks in advance for the help.
Usually, people rewrite the Windows functions they need to be std::string friendly, like this:
std::string GetCurrentDirectoryA()
{
char buffer[MAX_PATH];
GetCurrentDirectoryA( MAX_PATH, buffer );
return std::string(buffer);
}
or this for wide char support:
std::wstring GetCurrentDirectoryW()
{
wchar_t buffer[MAX_PATH];
GetCurrentDirectoryW( MAX_PATH, buffer );
return std::wstring(buffer);
}
LPTSTR is defined as TCHAR*, so actually it is just an ordinary C-string, BUT it depends on whether you are working with ASCII or with Unicode in your code. So do
LPTSTR lpStr = new TCHAR[256];
ZeroMemory(lpStr, 256);
//fill the string using i.e. _tcscpy
const char* cpy = myString.c_str();
_tcscpy (lpStr, cpy);
//use lpStr
See here for a reference on _tcscpy and this thread.
Typically, I would read the data into a TCHAR and then copy it into my std::string. That's the simplest way.

C++/CLI String Conversions

I found this really nice piece of code that converts a string to a System:String^ as in:
System::String^ rtn = gcnew String(move.c_str()); // 'move' here is the string
I'm passing rtn back to a C# program. Anyways, inside the function where this code exists, I'm passing in a System::String^. I also found some code to convert a System:String^ to a string using the following code:
pin_ptr<const wchar_t> wch = PtrToStringChars(cmd); // 'cmd' here is the System:String
size_t convertedChars = 0;
size_t sizeInBytes = ((cmd->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);
err = wcstombs_s(&convertedChars,ch, sizeInBytes,wch, sizeInBytes);
Now I can use 'ch' as a string.
This, however, seems to be alot more work than converting the other way using the gcnew. So, at last my question is, is there something out there that will convert a System::String^ to string using a similar fashion as with the gcnew way?
Use VC++'s marshaling library: Overview of Marshaling in C++
#include <msclr/marshal_cppstd.h>
// given System::String^ mstr
std::string nstr = msclr::interop::marshal_as<std::string>(mstr);
this could be useful:
wchar_t *str = "Hi StackOverflow"; //native
String^ mstr= Marshal::PtrToStringAnsi((IntPtr)str); // native to safe managed
wchar_t* A=( wchar_t* )Marshal::StringToHGlobalAnsi(mstr).ToPointer(); // return back to native
don't forget using namespace System::Runtime::InteropServices;

How to convert PUNICODE_STRING to bstr?

I'm calling a function which is in a ComVisible managed dll from a VC++ code. In the managed dll the function parameter type is string.
In the VC++ code i've the variable as PUNICODE_STRING. How can i pass it to the function? How can i convert it into BSTR?
Thank you.
NLV
The first thing to note is that PUNICODE_STRING's internal string buffer might not be null-terminated. So it would be best to go via a standard null-terminated wide string, that can then be passed straight to SysAllocString.
Try this:
BSTR PUNICODEToBSTR(PUNICODE_STRING pStr)
{
// create a null-terminated version of the input string
wchar_t* nullTerminatedString = new wchar_t[pStr->Length + 1];
memset(nullTerminatedString, 0, sizeof(wchar_t) * (pStr->Length + 1)];
wcsncpy(nullTerminatedString, pStr->Buffer, pStr->Length);
// create a BSTR
BSTR bstrString = ::SysAllocString(nullTerminatedString);
// tidy-up and return the BSTR
delete [] nullTerminatedString;
return bstrString;
}

Resources