|
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?
|
|
|
|
|
zaza_nata wrote:
In other words, is it possible to use #include
instead of #using as in MFC?
The short answar: No...
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
I'm living a trouble with managed c++ that below code doesn't work properly so it has generated following error;
test.cpp(25) : error C2440: '=' : cannot convert from 'classB __gc *' to 'void *'
Cannot convert a managed type to an unmanaged type
Code at following;
<br />
typedef struct {<br />
void* memberA;<br />
} classA;<br />
<br />
typedef struct {<br />
int int_memberB;<br />
char* cp_memberB;<br />
} classB;<br />
<br />
__gc class ManagedClass {<br />
private:<br />
classA m_classA;<br />
classB m_classB;<br />
<br />
public:<br />
ManagedClass()<br />
{<br />
m_classA.memberA = &m_classB;<br />
}<br />
<br />
virtual ~ManagedClass()<br />
{<br />
}<br />
};<br />
How can i solve that problem?
Some must watch while some must sleep...
OGED
|
|
|
|
|
Ahmet Orkun GEDiK posted:
Cannot convert a managed type to an unmanaged type
You are trying to keep a pointer to a managed object, in an unmanaged class. Managed objects live on the GC heap, which is not the same as regular heap memory. Locations/pointers to managed stuff can actually change during an app's lifetime (which would invalidate your pointer), and .Net does not update pointers in unmanaged objects, only in managed ones.
Although there are ways to coerce .Net to reveal the numeric address of managed objects, it would require pinning the managed object first, then using it for a very short period of time before unpinning it. If not, the GC is prevented from managing its heap properly. It would be more appropriate to get a pointer to a managed object (such as m_classB here) for use by an unmanaged object, as needed, and for no longer.
If you could explain how you need to use a managed pointer in an unmanaged context, perhaps I could provide a solution.
Cheers
|
|
|
|
|
Is that mean we cannot use old libraries or structures?
Ahmet Orkun GEDiK
|
|
|
|
|
Ahmet Orkun GEDiK wrote:
Is that mean we cannot use old libraries or structures?
No, unmanaged structures can be used, and in general C++ library routines can be mixed-in with MC++. The catch is in how managed and unmanaged code is used together. Managed data can usually be "marshaled" over to unmanaged stuff, but the way your first post was written, an unmanaged type tried to hold a pointer to a managed object, and for an unknown amount of time. Data from managed objects can be copied over to unmanaged code, but unmanaged code should not try to keep pointers to managed objects around. Only managed code should keep pointers around to other managed objects.
In other words, managed code is fairly happy referencing unmanaged data, but it's not so simple the other way around.
|
|
|
|
|
Ok. Sounds great. But how will i solve my problem ?
typdefsampleDlg.cpp(26) : error C2440: '=' : cannot convert from 'SAMPLE __gc *__w64 ' to 'void *'
Cannot convert a managed type to an unmanaged type
Can you give an example to me ?
Ahmet Orkun GEDiK
|
|
|
|
|
You do not store a managed pointer in an unmanaged object. If you could explain why you wanted to store it, and what it was to be used for, perhaps I could explain a workaround, but without that information, I can't provide a suggestion.
|
|
|
|
|
Ok. I'm using a library that uses standart C++ routines. One function need to assignment such as following;
RFC_OPTIONS rfc_option;
RFC_CONNOPT_R3ONLY rfc_connopt;
rfc_option.connopt = & rfc_connopt;
type definitions at below;
typedef struct
{
rfc_char_t * hostname;
int sysnr;
rfc_char_t * gateway_host;
rfc_char_t * gateway_service;
}
RFC_CONNOPT_R3ONLY;
typedef struct
{
rfc_char_t * destination;
RFC_MODE mode;
void * connopt;
rfc_char_t * client;
rfc_char_t * user;
rfc_char_t * password;
rfc_char_t * language;
int trace;
}
RFC_OPTIONS;
So as i metioned, rfc_option.connopt = & rfc_connopt; has generate error.
Ahmet Orkun GEDiK
|
|
|
|
|
One way to do this would be to keep an unmanaged struct around for passing to RfcOpen() calls. I assume you will get your string data as CLR String types, so you might want to keep them around in a .Net/GC struct for convenience, as done here (see m_RfcConnopt). When m_RfcConnopt has been filled, its data can be copied into unmanaged data. In this example the CLR Strings are converted to char strings, and then copied into C++ strings for long-term keeping (optional).
using namespace System::Runtime::InteropServices;
__gc struct RFC_ConOpt
{
String* sHostName;
Int32 sysnr;
String* sGatewayHost;
String* sGatewayService;
};
RFC_ConOpt *m_RfcConnopt;
std::string sHostName, sGatewayHost, sGatewaySvc;
IntPtr ptr = Marshal::StringToHGlobalAnsi(m_RfcConnopt->sHostName);
sHostName = (char*)ptr.ToPointer();
Marshal::FreeHGlobal(ptr);
ptr = Marshal::StringToHGlobalAnsi(m_RfcConnopt->sGatewayHost);
sGatewayHost = (char*)ptr.ToPointer();
Marshal::FreeHGlobal(ptr);
ptr = Marshal::StringToHGlobalAnsi(m_RfcConnopt->sGatewayService);
sGatewaySvc = (char*)ptr.ToPointer();
Marshal::FreeHGlobal(ptr);
rfc_connopt.hostname = &(*sHostName.begin());
rfc_connopt.gateway_host = &(*sGatewayHost.begin());
rfc_connopt.gateway_service = &(*sGatewaySvc.begin());
rfc_connopt.sysnr = m_RfcConnopt->sysnr;
rfc_option.connopt = &rfc_connopt;
You could skip copying the char strings into the C++ strings here. I just did that to avoid having to remember to call Marshal::FreeHGlobal() later on. The important thing is that .Net's wchar_t strings need to be converted to unmanaged char strings, and that rfc_option.connopt needs to point to an unmanaged array.
|
|
|
|
|
That's very nice approach. But I can't change the structure because that function in a DLL. I can interfere to interface of the library.
Ahmet Orkun GEDiK
|
|
|
|
|
Hi
i am begginer in Visual C++ and i have a quiestion.
assume that we have an Window. in this Window we have some objects . for example we have 3 ICON in the window. how can i simply Drag one ICON(object) and move it everywhere i want and Drop it.
i don't want to use CImageList because using this Class we can't Drag 2 object altogher and we can Drag 1 image on each Drag-n-Drop operation.
if u want to underStand what i want to do See this Amazing applet :
http://www.seanet.com/users/arsen/avltree.html
in this AMAZING AVL Tree(that uses in DataStructure) u can Simply Drag a Node every where u want and Drop it. u can see that When u Drag a Node all of the Nodes are move altogether.
how can i do that ? Plzzz helpp meeee
|
|
|
|
|
Hi, I have a problem (I think a big problem).
The language is C++. The operation sistem is Windows 2000.
If I create two application. In the first application fill a structure, open a file and send this information (pointer to file) at second application which fill the file. When the second application end your job, the control switch at first application which close the file.
The question is:
can I open a file in a application sending the pointer at second applicaton to fill the file.
|
|
|
|
|
You can use inter-process communication for communicate two or more processes. Take a look Threads, Processes & Inter-Process Communication title.
Ahmet Orkun GEDiK
|
|
|
|
|
Hi, I have a problem (I think a big problem).
The language is C++. The operation sistem is Windows 2000.
If I create two application. In the first application fill a structure, open a file and send this information (pointer to file) at second application which fill the file. When the second application end your job, the control switch at first application which close the file.
The question is:
can I open a file in a application sending the pointer at second applicaton to fill the file.
|
|
|
|
|
Yes, you can do so.
You can make the pointer as a syetem parameter which will be sent to another application. And the another application will get the system parameter--the pointer when the specified application is going to run. I guess you are sure to know that an application can accept command line that is just system parameter. Good luck!
stanley
|
|
|
|
|
I have created a service in c#.
And I am executing a Process.Start command in this code ( OF SERVICE PROJECT) .
that command(Process.Start ) is executing sucessfully for local drives but it throws Win32Exception (means There was an error in opening the associated file) at network path. for example path is \\computername\folder1\folder2\some.exe
AND it heapens only with Service type application all other applications are executing any process at network path (i.e \\computername\folder1\folder2\some.exe)successfully with this command(Process.Start).
Can any body tell how will I make my Service to execute any Process at network path?
r00d0034@yahoo.com
|
|
|
|
|
As default a service runs as the "System" user. This user dont have permissions to access shares on other computers.
You have to change toe user that the service logs on as. Change that to a user that have permissions to access the share, then it works
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
I still can't find out how to convert this managed string into a unmanaged char[20].
Specifically: I have a char called FILENAME
char filename __nogc[20] ;
and a managed string called STR.
String* str ;
Does anyone have any idea how to read STR into FILENAME?
Please don't tell me it can't be done...
Thanks,
KBL
|
|
|
|
|
|
is for Managed Visual C++.NET..
Suppose I have two Strings.
String1 = C://files
String2 = data.txt
I want to concatenate the two strings while inserting a character between them, to get a new string:
C://file/data.txt
Here the character is an extra "/".
Once this is done, I would like to convert the new string to a char[20].
Does anyone know how to perform this task?
I would be very grateful..
Thanks
KBL
|
|
|
|