|
You have the wrong forum; the Visual C++ forum is for regular C++ questions. However, you might want to use the new-style C++ headers, which omit the ".h":
#include <iostream>
and make sure you include:
using namespace std;
or use "std::cout".
|
|
|
|
|
Thanks Jeff it solved the problem .
Sorry about wrong forum.
|
|
|
|
|
Please, can anyone say me reasons for buying VS.Net and using managed C++ instead unmanaged C++ (and C# instead Java for Web) ?
Except compatibility ( "you can use this applications anywere... where Windows and .Net framework installed, heh ")and fashion reasons %)
I'm sorry for this vulgar question, but i cant find this reasons by myself.
Can anyone help me ?
P.S. I forgot - call "delete" for any called "new" is not a problem for me
WBR NB
|
|
|
|
|
Hello All,
What is the recommended way to handle strings out parameters
of functions/methods?
Interestingly, I could not find single example in any book and just
not confidence on which way will work and across languages like
VB.NET and C#.
Any help?
The simply one I am currently considering (which works) is:
#using <mscorlib.dll>
using namespace System;
using namespace System::Text;
void GetString(StringBuilder* pOut)
{
pOut->set_Length(0);
pOut->Append("Out--string");
}
int _tmain()
{
StringBuilder* pOut = new StringBuilder("In--string");
GetString(pOut);
Console::WriteLine(pOut->ToString());
return 0;
}
Any better solution? Something that could be used in other languages too.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
If all you are looking to do is get a String/StringBuilder back when passed as a parameter, then passing by reference will achieve what you want. Your current example would need to be modified to something like:
void GetString(StringBuilder **pOut)<br />
{<br />
(*pOut)->set_Length(0);<br />
(*pOut)->Append(S"Out--string");<br />
}
This is very COM-like, and both C# and VB.Net prototypes will ask for a reference, such as:
void GetString(ref StringBuilder pOut); //in C#
which would be called like:
GetString(ref pOut);
GetString(ByRef pOut);
GetString(&pOut);
For various reasons, just asking for a pointer to a parameter is not enough with the CLR (unlike in C++); one must ask for a pointer to a pointer in order for the modification to get back to the caller. Your current version may well work when the StringBuilder is not reallocated, but all bets are off after reallocation, since the callee will then have a pointer to a new object (and this is always the case when passing String).
I believe there is also a way to make the call look like:
void GetString(out StringBuilder pOut); //C#
but I have not bothered so far, as I am waiting for finalisation of VS 2003 with possibly further MC++ refinements, and I have also not really needed to do so.
When passing by the CLR's definition of "by ref", you will no longer need to pre-size the StringBuilder before calling GetString():
int _tmain()<br />
{<br />
StringBuilder *pOut = new StringBuilder();<br />
GetString(&pOut);<br />
Console::WriteLine(pOut->ToString());<br />
return 0;<br />
}
That is probably obvious to you, but it is mainly why I have used passing by ref. For example, I have written some MC++ functions that are expected to be called repeatedly. They take StringBuilders by ref specifically so that internal arrays rarely need to be reallocated, and I suspect you might be trying to do the same. I have also done this with plain CLR strings, though reallocation would need to occur on each call:
void GetString(String **ppStr)<br />
{<br />
*ppStr = new String(S"Out--string");<br />
}
However, if the function has no length of string to return, then chars do not have to be allocated for nothing. I hope some of this is valid for your purposes
Cheers
|
|
|
|
|
Hello Jeff,
Thanks so much for taken the time to explain this so well. I tried the pointer to pointer stuff in an out System::Drawing::Rectangle case, and the compile will not work claiming it is a value and that I should use the "__nogc new" instead:
void GetRectangle(Rectangle** pOut)
{
*pOut = new Rectangle(...);
}
Not knowing whether the C++ heap will be accessible or not from other languages, I changed it to reference like this:
void GetRectangle(Rectangle& pOut)
{
pOut.X = ;...
}
However, the IL output from the MC++ seems to carry some VC specific information attached to the parameter:
modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier)
So, I got confused as to what will really be accepted as the standard way of doing it.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Well, I just got this response on the VC news group:
There is no real need to change to pointers. C# handles this fine. The
"modopt" means that it is an OPTional MODifier for the signature. When the
C++ compiler sees it it know to treat it as a C++ reference, the C# compiler
will just treat it as a byref parameter.
Ronald Laeremans
Visual C++ team
It seems the modopt stuff is "safe" to work with
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi Paul,
Thanks for the bit from the Ronald Laeremans; there's nothing like inside info I had been wondering why the compiler treats pointers to __value parameters the same as declaring them as C++ references. Knowing that this stuff is ".Net official" makes me feel better about the future for code I've written. Please feel free to post anything else you get from the inside!
Sorry I didn't cover passing __value types in my first post; I was only talking about types that are already "CLR reference object"/pointer types, when I talked about pointers to pointers. I pass __value types the same way you did (as a C++ reference), and skip the pointer syntax.
Cheers,
Jeff
|
|
|
|
|
I met a problem when I tried to wrap unmanaged class into managed class with managed C++.
First, I built a static library, VcClass.lib, from the following source code with VC++ 6.0 :
/* interface.h */
#include <windows.h>
class CMyClassA
{
public:
BYTE *m_pBuf;
int m_bufLen;
CMyClassA() { m_pBuf = NULL; m_bufLen = 0; }
~CMyClassA() { FreeBuf(); }
HRESULT LoadBuf(BYTE *pBuf, DWORD dwBufLen);
private:
HRESULT FreeBuf(void);
};
class CMyClassB
{
public:
CMyClassB() { m_pA = NULL; }
~CMyClassB() { m_pA = NULL; }
HRESULT Func(CMyClassA *pClassA);
HRESULT Func2(void);
private:
CMyClassA *m_pA;
};
#endif
/* VcClass.cpp */
#include <stdio.h>
#include "interface.h"
HRESULT CMyClassA::LoadBuf(BYTE *pBuf, DWORD dwBufLen)
{
m_bufLen = dwBufLen;
m_pBuf = new BYTE[m_bufLen];
memcpy(m_pBuf, pBuf, m_bufLen);
return 0;
}
HRESULT CMyClassA::FreeBuf(void)
{
m_bufLen = 0;
delete [] m_pBuf;
return 0;
}
HRESULT CMyClassB::Func(CMyClassA *pClassA)
{
m_pA->m_pBuf = pClassA->m_pBuf;
m_pA->m_bufLen = pClassA->m_bufLen;
for (int i=0; i<m_pa->m_bufLen; i++)
printf("buf[%d] = %d\n", i, m_pA->m_pBuf[i]);
return 0;
}
HRESULT CMyClassB::Func2(void)
{
if (m_pA->m_pBuf == NULL) {
printf("buf is empty, call Func() first!\n");
return 1;
}
for (int i=0; i<m_pa->m_bufLen; i++)
printf("buf[%d] = %d\n", i, m_pA->m_pBuf[i]);
return 0;
}
then, I wrote two wrapped classes with VC++ 7.0 and compiled them into a DLL:
#include "interface.h"
using namespace System;
namespace McClass
{
public __gc class McMyClassA
{
public:
McMyClassA() { m_pClassA = new CMyClassA; }
~McMyClassA() { delete m_pClassA; }
int LoadBuf(System::Byte Buf[], int Len)
{
System::Byte __pin * p = &Buf[0];
return m_pClassA->LoadBuf(p, Len);
}
void *GetA() { return (void*)m_pClassA; }
private:
CMyClassA * m_pClassA;
};
public __gc class McMyClassB
{
public:
McMyClassB() { m_pClassB = new CMyClassB; }
~McMyClassB() { delete m_pClassB; }
int Func(McMyClassA *pMA)
{
CMyClassA *pA = (CMyClassA*)pMA->GetA();
return m_pClassB->Func(pA);
}
int Func2(void)
{
return m_pClassB->Func2();
}
private:
CMyClassB * m_pClassB;
};
}
Finally, I wrote an application with C# to call the DLL:
using System;
using McClass;
namespace CSharpApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int i;
McMyClassA classA = new McMyClassA();
McMyClassB classB = new McMyClassB();
Byte[] buf = new Byte[10];
for (i = 0; i<10; i++)
buf[i] = 54;
classA.LoadBuf(buf, 10);
classB.Func(classA);
Console.WriteLine("OK.");
classB.Func2();
Console.WriteLine("OK.");
}
}
}
When I run the C# application, a NullRefrenceException occurred and the additional information is :
Unhandled Exception: System.NullReferenceException: Object reference not set to
an instance of an object.
at CMyClassB.Func(CMyClassB* , CMyClassA* )
at McClass.McMyClassB.Func(McMyClassA pMA)
at CSharpApp.Class1.Main(String[] args)
I think that the exception occurs because I used a wrong approach to pass a pointer of MyClassA into an instance of MyClassB.
So, what is the right way to do it? Data Marshal?
I hope MyClassA is independent on MyClassB, therefore I don’t want to merge MyClassA and MyClassB into one class.
Please help me!
Thank you very much!
|
|
|
|
|
sorry, I made a mistake.
please don't reply.
thanks.
|
|
|
|
|
deadlock, this is the problem of not logging in before posting. You could have deleted the thread.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello All,
Why do we need the static constructors in MC++? Is it to show that we have something to learn from C#?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I am having difficulty handling a vector<std::string> that is returned from unmanaged code and then converting it to an ArrayList of String. I get the following error: cannot convert parameter 1 from 'std::string' to 'System::Object __gc *
How do I Marshal this?
#ifndef __STAT_H__
#define __STAT_H__
#include <vector>
#include <string>
// Unmanaged file
class CStatus
{
public:
std::vector<std::string> statuses;
CStatus() {}
};
#endif
// EOF
// in Managed file
ArrayList statuses = new ArrayList();
CStatus stat;
int iReturn = SubmitJob( stat);
for (unsigned int ivector = 0; ivector < stat.statuses.size(); ivector++)
{
statuses->Add((stat.statuses[ivector])); // ERROR occurs
}
Thanks for all advice.
|
|
|
|
|
You only have to marshal your strings to CLR Strings, since all CLR reference types (including String) are based on Object. Then you can Add() your Strings to an ArrayList.
If your std::strings are strictly lower ASCII (and I do mean 7-bit ASCII, not MBCS/ANSI), the following method will work:
using namespace System;<br />
using namespace System::Collections;<br />
using namespace System::Text;<br />
using namespace std;<br />
<br />
vector<string> vec;<br />
string s = "a std::string";<br />
vec.push_back(s);<br />
<br />
ASCIIEncoding *enc = new ASCIIEncoding();<br />
String *sCopy = new String(vec[0].c_str(), 0, vec[0].size(), enc);<br />
<br />
ArrayList *al = new ArrayList();<br />
al->Add(sCopy);
For anything beyond English, you will need to use either Marshal::PtrToStringAnsi() or MultiByteToWideChar(). I could explain that if it's what you need instead.
Cheers
|
|
|
|
|
I want to create a simple web-page that contains a button that, when pressed, reads data from a database (Access) and produces graphs with the data retrieved.
How should I do this with Visual C++? Maybe ActiveX programming?
I need general orientation and online tutorials on this.
I'd appreciate any help regarding this, thanks.
-- narada
|
|
|
|
|
Search MSDN for ".Net", "C#" and "Web Controls"
Or if you do not like .Net
Serach for "ATL" and "Web Server"
Or if you want to use Active X
Search for "ATL" , "COM" "Active X" and "WEB page"
Or if you want to go one level below
search for "ISAPI"
etc..
You have many choices, you have to chose the approach according to you level, time constraints and general direction of the company (some people prefer Perl )
|
|
|
|
|
Thanks so much!
-- narada
|
|
|
|
|
Hello everyone.
How can build an exe file by VS .NET to execute it on Windows_98?
Thank you
|
|
|
|
|
If you're using traditional unmanaged C++ then you should be able to deploy it as with any previous Visual C++ output. If you use MFC then you can link statically to prevent having to send out anything other than the EXE. If you're linking to the shared MFC library then you'll have to distribute the MFCxx.dll too.
If you're using Managed C++ (and I'm assuming you are since its in the MC++ forum) then you'll have to install the .NET Runtime on the target machine too.
The code compiled from VC#, VB.NET or VC++ using /clr will be MSIL, this is then JIT compiled when its first run courtesy of the .NET CLR.
The .NET Runtime ought to be on the VS.NET CDs somewhere, alternatively it'll be available from MSDN -- sorry I don't have the link off-hand.
--
Paul
"If you can keep your head when all around you have lost theirs, then you probably haven't understood the seriousness of the situation."
- David Brent, from "The Office"
MS Messenger: paul@oobaloo.co.uk
Sonork: 100.22446
|
|
|
|
|
For future reference we would appreciate it if you would not post the same question more then once across the different message boards, I believe you asked this exact question in the .NET Framework board also. Thanks
"We will thrive in the new environment, leaping across space and time, everywhere and nowhere, like air or radiation, redundant, self-replicating, and always evolving." -unspecified individual
|
|
|
|
|
In unmanaged C++ code, I have a vector of a class of instances that contains a vector of instances of another class (which actually also contains a vector of instances of another class).
public class1
{
private:
double xLocation;
double yLocation;
vector <subclass1> sub1;
//methods, etc.
}
public Subclass1
{
private:
double zLocation;
vector <subclass2> sub2;
//methods, etc.
}
public Subclass2
{
private:
double value1;
double value2;
//methods, etc.
}
I get this all populated in unmanaged C++ code. However, I then need to get this to a C# front end via managed C++. Should I convert this structure in the managed file? Convert the vectors to ArrayLists? What is the best way to do this? Has anyone done this? Thanks for any help/advice.
|
|
|
|
|
It is unclear exactly how you need to pass the vector data, whether anything needs to be modified in C#, and so forth. One question is whether you could re-implement all this in MC++ (or C#) from scratch to begin with. That is, populate ArrayLists from the get-go.
If you have no choice but to pass unmanaged stuff to managed code, you will likely need to copy everything into managed (GC-collected) memory. If everything is largely primitive types (except the vectors, of course), then that shouldn't be too bad. If you need to pass values/changes back to unmanaged code, you will have to copy again. Obviously, it is best to minimise how much data must be marshaled back and forth between unmanaged and managed memory.
If the "vectors" need to be dynamic within C#, then ArrayList seems like a reasonable choice, though performance will not be as good (if nothing else but because everything will have to be handled by pointers to the base Object class). If performance is not a major consideration, then go that way. If nothing needs to be modified (i.e., not dynamic) in C#, then __gc[] arrays are more efficient, and more flexible in MC++ than in C#.
If you can be more specific about how the vectors need to be used, perhaps I could be more specific with any suggestions. I have been swimming in the regions between C++ and MC++ for quite a while now.
Cheers
|
|
|
|
|
Hi, I just swtiched to the .NET for my programming. I have
an error for my first Visual C++ .Net project:
error LNK2001: unresolved external symbol "public:
__thiscall TEnv::TEnv(float)" (??0TEnv@@$$FQAE@M@Z)
What I did is the following:
1. Open a blank solution.
2. Add a new project Test (Managed C++ Application)
3. Add another new project TObject (Managed C++ Class
Library)
4. Define a class TEnv in the TObject with the constructor
TEnv(float t), but this constructor is implemented in
the .cpp file.
Then I begin to use class TEnv in the main() function
inside project Test... I got this error. I am afraid the
project setting is wrong, but I haven't be able to figure
out why. It works in the good old days in Visual Studio...
Thanks, and Merry Xmas!
|
|
|
|
|
|
In Visual C++ .Net we created a managed class, whose definition is
in myclass.h, and implementation is in myclass.cpp.
After that we created a library based on these files (DLL).
Now we want to use this class in our application (EXE).
We perform compilation from a command line (it is a requirement).
In our application, we write #include "myclass.h" and also
#using "mydll.dll", but now we get an error during compilation.
Compiler generates an error because declaration of our class is
both in the header and the DLL, since we used #using directive.
But if we remove #using, then compiler does not understand
where our class' members are.
Thus, we should not include our header file, but should add
an option /FUmydll.dll to the compiler (cl.exe), then everything
works.
Question: is it possible to avoid adding a compiler option /FU,
so that we could include our header file in our application and
the DLL was linked dynamically (i.e., during run-time as in MFC),
not statically? In other words, is it possible to use #include
instead of #using as in MFC?
|
|
|
|
|