|
I have a problem, i want to open an .xls file with one sheet in c++ builder and after that i opened the document i want to copy two columns in a .txt file with a tab between the columns.
|
|
|
|
|
Hi, I need your advice on the complexity involved in using a Windows forms GUI for a program that is written in unmanaged C++.
The program does data acquisition and live processing of data, all accomplished in native C++. I need to add a UI for the program that should basically allow the user to set the initial parameters, then once acquisition and processing begins the UI should show some status updates to the user and draw live plots of the processed data that the user would like to see.
I would rather use forms for the GUI due to the simplicity of the designer and ease of integration with VC++ (MFC is not an option), but I have only come to know of C++/CLI recently, which made me wonder about the difficulty involved with getting the form to call and interact with unmanaged code, compared to using a native C++ GUI design library like Qt (or something else you would suggest that is not MFC).
I have a short amount of time as I am on an internship, so I do not want to spend time learning the wrong library for the job. Any help you can provide would be greatly appreciated.
Thanks
|
|
|
|
|
If you don't expect portability, C++/CLI is worth trying. Developing a GUI with C++/CLI is trivial. You can do communication with your unmanaged API easily.
|
|
|
|
|
Portability isn't a priority since some of the core DLL's I am using only work with windows, though I suppose at least the Form code should be portable using Mono.
I have made a simple form and added a member function that is coded in native C++ (uses pointers, new/malloc, etc.) with no problems, so I guess my fears were unfounded. Though out of curiosity, how does this program work when some of its code is compiled to MSIL and others to machine code? and does that negatively affect performance during run-time?
|
|
|
|
|
Your native code will run at the usual speed, it won't operate any slower because it's running in the context of a managed application. The only performance issues you could potentially run into are the serialization/marshaling time required to use to convert your initial parameters from managed types to native types (negligible) and the resulting native data into managed types that can be plotted or otherwise shown on your form (probably negligible.) If you're talking about querying and plotting the data with seconds or more between each update, there shouldn't be much of a problem. If you're talking about updating multiple times per second, however, you could potentially run into some slow-downs.
Adam Maras | Software Developer
Microsoft Certified Professional Developer
|
|
|
|
|
Adding to the other reply, C++/CLI uses C++ interop to do managed - unmanaged communication. C++ interop is quite fast and you don't find much problems with that.
|
|
|
|
|
I have to convert a string of format "2009/07/30" to DATE in managed C++.
There is a parse method in DATE. But I don't know how to use that.
Please help me with the format.
|
|
|
|
|
DateTime myDate = DateTime::Parse("2009/07/30");
Don't be overcome by evil, but overcome evil with good
|
|
|
|
|
|
hello
I'm trying to pass multi-dimensional arrays from C# to un-managed WIN32 C++ dll - second parameter of each of the two functions exported below are meant to be OUTPUT parameter (memory allocated in C# however)
<br />
MATLABGENERICDLL_API void GetCurves(char* strParam, double * myCurve)<br />
{<br />
for(int i=0; i<10; i++)<br />
{<br />
if(i>0) {<br />
myCurve[i] = 1.01 * Curve[i-1];<br />
} else {<br />
myCurve[i] = 0.5;<br />
}<br />
}<br />
return;<br />
}<br />
<br />
MATLABGENERICDLL_API void GetMatrix(char* strParam, double ** myMatrix)<br />
{<br />
try {<br />
for(int i=0; i<10; i++)<br />
{<br />
for(int j=0; j<10; j++)<br />
{<br />
myMatrix[i][j] = 0.25;<br />
}<br />
}<br />
} catch( ...)<br />
{<br />
throw;<br />
}<br />
<br />
return;<br />
}<br />
GetCurves executed successfully, but not GetMatrix.
<br />
class Program<br />
{<br />
[DllImport(@"C:\MatlabGenericDll.dll")]<br />
private static extern string ToUpper2(string Src);<br />
<br />
[DllImport(@"C:\MatlabGenericDll.dll")]<br />
private static extern void GetCurves(string strParam, [In, Out] double[] myCurves);<br />
<br />
[DllImport(@"C:\MatlabGenericDll.dll")]<br />
private static extern void GetMatrix(string strParam, [In, Out] double[,] myMatrix);<br />
<br />
static void Main(string[] args)<br />
{<br />
string strTest = "abc";<br />
string strResult = null;<br />
<br />
double[] myCurve = null;<br />
double[,] myMatrix = null;<br />
<br />
try<br />
{<br />
strResult = ToUpper2(strTest);<br />
<br />
myCurve = new double[100];<br />
GetYieldCurves("AAA", myCurve); << For some reason, executed succssfully (Although I checked &myCurve - address seems to be different in C#/C++ layer so I really don't understand why it worked)<br />
<br />
myMatrix = new double[10, 10];<br />
GetMatrix("BBB", myMatrix); << System.AccessViolationException, complained saying memory probably corrupted.<br />
}<br />
catch (Exception ex)<br />
{<br />
Console.WriteLine(ex.ToString());<br />
}<br />
<br />
return;<br />
}<br />
}<br />
I'm not sure if I am doing right thing ... allocating memory from C# layer and if C# exe and C++ dll share same address space at all.
My end goal is: I actually also need to pass, from c# exe to unmanaged C++ dll, a two-dimensional array of undetermined size of different column types (string, doubles, int, DateTime)
Thanks!
http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx
dev
modified on Thursday, July 30, 2009 2:00 AM
|
|
|
|
|
Hi,
in native code all arrays are actually one-dimensional, i.e. all the elements are on consecutive addresses.
in managed code you have two kinds of multi-dimensional arrays, and their lay-out isn't what the native world needs at all. So if you manage to get it marshalled, all data will have to be copied.
If OTOH you declare a managed one-dimensionl array, you could use either the fixed keyword or the GCHandle class to obtain the data pointer and pass that, no copying involved.
So rather than using array[x][y] I would recommend something along the lines of aray[x*YDIM+y] (or is it y*XDIM+x, not sure).
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
hi, i have a managed c++ project using /clr using old syntax.
one of the functions in the program has the following argument list: (System::Object __gcc * _gcc yValue[])
i'm trying to pass four doubles in an array, but am having difficulty with the notation.
any help?
thank you
|
|
|
|
|
Member 3153721 wrote: i'm trying to pass four doubles in an array
What type of array? An array of System::Object references?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
it can be any one of these types: String DateTime Double Decimal Single Int32 UInt32 Int64 UInt64
it's for a winforms control. here is the link to the full method description: http://support.dundas.com/OnlineDocumentation/WinChart2005/topic1363.html[^]
from the documentation, i 'should' be able to just list values in the argument, so AddY(1,2,3,4). however, managed c++ does not convert the values to an array. creating the array first and then passing the variable in the argument will not compile... it apparently does not reconginze the array value. i've come up with a work around using another set of functions in the library, but it's very difficult to get managed code to play nice with windows forms libraries to say the least.
|
|
|
|
|
function declaration should look rather like the following:
int AddY(System::Object __gc * yValue __gc []);
or
int AddY(System::Object* yValue[]);
params keyword isn't supported in C++, so this function should be called with argument of type array of Object*.
int AddY(Object* yValue[])
{
return yValue->Length;
}
Object* arr[] = new Object*[2];
ar[0] = __box(1.1);
ar[1] = __box(2.1);
AddY(arr);
|
|
|
|
|
I am using Visual C++ 2005 NET.
How can I write in status bar when the mouse is over the button or when I am runing a process, I can show a message in status bar.
|
|
|
|
|
mikobi wrote: How can I write in status bar
Take a look at the StatusBar Class Documentation[^]. No doubt there is something in there that will help you.
|
|
|
|
|
i have implemented the dfs algo in c++ using recursion but i wish to find all routes from source to destination. any good article or guidelines will helpful..i wish to do it using a link list if possible..!!!
|
|
|
|
|
|
Hi,
I'm doing a simple managed C++ class to grab data from a USB device and pass it to the C# side.
This is my class:
public __gc class Communication<br />
{<br />
private:<br />
LPVOID dataInBuffer; <br />
HANDLE _hFileHandle;<br />
int nBytesToRead; <br />
int maxPacketSize;<br />
<br />
public:<br />
<br />
Communication()<br />
{<br />
_hFileHandle = INVALID_HANDLE_VALUE;<br />
<br />
maxPacketSize = 256;<br />
dataInBuffer = malloc(sizeof(char) * maxPacketSize);<br />
nBytesToRead = maxPacketSize;<br />
}<br />
<br />
~Communication()<br />
{<br />
if( _hFileHandle != INVALID_HANDLE_VALUE )<br />
{<br />
CloseHandle( _hFileHandle );<br />
}<br />
}<br />
<br />
bool OpenDevice( String* driverName )<br />
{<br />
char* lpFileName = new char[driverName->Length + 10];<br />
<br />
sprintf( lpFileName, "\\\\?\\%s", driverName );<br />
<br />
_hFileHandle = CreateFile((LPCSTR) lpFileName,GENERIC_READ,0,0,OPEN_EXISTING,0,0);<br />
<br />
if( _hFileHandle == INVALID_HANDLE_VALUE )<br />
{<br />
puts("Couldn't not open device");<br />
}<br />
<br />
delete lpFileName;<br />
<br />
return( _hFileHandle != INVALID_HANDLE_VALUE );<br />
}<br />
<br />
BOOL CloseDevice()<br />
{<br />
return CloseHandle( _hFileHandle );<br />
}<br />
<br />
int GetPacket()<br />
{<br />
char outBuffer[256];<br />
<br />
int nBytesRead = -1;<br />
<br />
if (_hFileHandle!=INVALID_HANDLE_VALUE)<br />
{<br />
ReadFile(_hFileHandle, dataInBuffer, nBytesToRead, (PULONG) &nBytesRead,0);<br />
}<br />
<br />
memset(outBuffer,0,maxPacketSize*sizeof(char));<br />
memcpy(outBuffer,dataInBuffer,maxPacketSize*sizeof(char));<br />
<br />
return nBytesRead;<br />
}<br />
};
My problem right now it how to pass the outBuffer variable in the GetPacket method outside the class.
If I let the variable being declared inside the function, it gets erase when the function ends and my data goes with it.
If I declare that variable in the class itself, the compiler says the following:
'outBuffer' : must explicitly specify __gc or __nogc for an array declared in a managed type
And if I put the __gc attribute on the variable, then the compiler tells the following:
'identifier' : '__gc' can only be applied to a class, struct, interface, array or pointer
So... what do I have to do in order to make this variable available in the C# side?
I'm using char, because I need a signed 8-bit value on each position of the array.
Can anyone give me some lights here?
Thanks,
Nuno
|
|
|
|
|
You are using the obsolete Managed C++ syntax. Are you using a compiler that don't support C++/CLI? If not, I would suggest you to rewrite this in C++/CLI.
|
|
|
|
|
Hi,
You could try something like this:
#pragma once
#include <memory.h>;
#include <string.h>;
using namespace System;
namespace CnvBuffLib
{
public __gc class ConvertBuffer
{
const char __nogc * const _buffer;
static const int bsize = 256;
public:
ConvertBuffer()
: _buffer(new char __nogc [bsize])
{
}
~ConvertBuffer()
{
delete [] _buffer;
}
int GetPacket()
{
char tmp[] = {'t', 'e', 's', 't'};
int tmplen = sizeof(tmp);
char __nogc * _bp = const_cast<char*>(_buffer);
_bp = static_cast<char*>(memset(_bp, 0, bsize));
memcpy(_bp, tmp, tmplen);
return tmplen;
}
SByte GetData() __gc []
{
int rlen = strlen(_buffer);
if(rlen == 0)
return 0;
SByte result[] = new SByte[rlen];
char __pin * presult = &result[0];
memcpy(presult, _buffer, rlen);
return result;
}
};
}
|
|
|
|
|
CComPtr<iwshruntimelibrary::ifilesystem>fileSystem;
fileSystem->DeleteFolder((wchar_t*)ServerPath, VARIANT_TRUE);
fileSystem->DeleteFolder() is failing . Can I know when this happens and what could be the solution.
Thanks.
|
|
|
|
|
Read return code into a HRESULT and identify the return code.
|
|
|
|
|
It is most unlikely that the poster of this question is still waiting for an answer nearly eleven years later.
|
|
|
|
|