|
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
|
|
|
|
|
There are no overloaded + or += operators for Strings in MC++, so one must use the plain member functions:
String *String1 = S"C:\\files";<br />
String *String2 = S"data.txt";<br />
<br />
String1 = String::Concat(String1, S"\\", String2);<br />
<br />
<br />
char achCStr[20];<br />
<br />
wchar_t *pGuts = PtrToStringArray(String1);<br />
int iChrs = ::WideCharToMultiByte(CP_ACP, 0, pGuts, String1->Length, achCStr, 20, NULL, NULL);<br />
achCStr[iChrs] = '\0';
PtrToStringArray() was posted earlier at http://www.codeproject.com/script/comments/forums.asp?forumid=3785&select=364715#xx364715xx[^] , and explained 2 posts earlier in that thread.
String::Concat() returns a concatenated copy of between 2 and 4 strings, and since the lengths of all the Strings are calculated prior to assembling them into the returned String, should avoid multiple temporary copies usually associated with concatenation (nice!). Insert() works like strcat() when the start position is the same as the original String's length, but as you can see it requires an extra temporary String copy
It's undocumented, but when I do something like the above, I pass 'String1->Length+1' in WideCharToMultiByte(), which avoids having to add the terminating null character afterwards. Like CString and std::string, CLR Strings seem to always have a terminating null appended to them, and I have never seen a case where they haven't.
Cheers
|
|
|
|
|
Hi -
I have a question which is probably very simple...
I'm trying to build an application which requires an open-file dialog like the explorer in windows (or like any other app that works with files). I want to use Windows Forms in Visual C++.net.
Does anyone have some canned code that generates an open-file dialog with a TreeView to the left and a ListView to the right, that allows the user to select a file from the ListView by clicking on the appropriate icon?
I would be very, very grateful!
Thanks,
KBL
KBL
|
|
|
|
|
|
Visual Studio 6
** loads a string of "len" byte in message at the given index
** message has to be able to contain "len" + idx bytes
*/
void CMessageProtocol::LoadValueInMessage( char *message , int idx, string &command, int len )
{//private:
int i;
// this loop load the command in message
for ( i = 0; command[i] && (i < len) ; i++ )
{
message[idx] = command[i];
idx++;
}
// this loop is used for padding
for ( ; i < len; i++)
{
message[idx] = PROT_PADDING;
idx++;
}
}
Visual Studio .NET
void GEMBrokerMessengerProtocol::CGEMMessageProtocol::LoadValueInMessage(SByte* Message,
Int32 idx,
System::String& Command,
Int32 len)
{
Int32 i;
// This loop loads the command in the message
// We need to convert the value of i(Int32(int)) to
// command(System::String&)
for(i = 0; Command[i] && (i < len); i++) {
Message[idx] = Command[i];
idx++;
}
// This loop is used for padding
// this loop is used for padding
for ( ; i < len; i++)
{
Message[idx] = PROT_PADDING;
idx++;
}
} When i try and compile I get the following errors:
c:\Documents and Settings\mdyer\My Documents\Visual Studio Projects\CGEMBroker\GEMBrokerMessengerProtocol.cpp(83): error C2676: binary '[' : 'System::String' does not define this operator or a conversion to a type acceptable to the predefined operator
Ha! And I though .NET was going to be cool!! I'm gaining a headache pretty fast!
|
|
|
|
|
I don't use managed c++ very often so I could be way off, but I think you need to use the String::Chars property to access a specific character in MC++ String.
- monrobot13
|
|
|
|
|
monrobot13 already answered your question, but just to give a syntax example:
for(i=0; Command->get_Chars(i) && (i < len); i++) {
dyerstein wrote:
Ha! And I though .NET was going to be cool!! I'm gaining a headache pretty fast!
I keep a bottle of pain relievers around for the headaches (not that it helps much), but I can't say the transition to MC++ is exactly fun. C# is a much better fit for .Net, however MC++ is our only practical way to use C++ with it.
Cheers
|
|
|
|
|
Hello;
I'm in trouble with memory leaks. Everthing going good until try to delete cphostname and cpclient at destructor. System has losing reference of objects that makes memory leak and annoying. How can i delete these variables from memory? Source code below.
public __gc class CSample {<br />
private:<br />
<br />
char* cphostname;<br />
char* cpclient;<br />
<br />
static const int HOST_NAME_SIZE = 17;<br />
static const int CLIENT_SIZE = 4;<br />
<br />
public:<br />
CSapR3Rfc()<br />
{<br />
try {<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
}<br />
catch(...) {<br />
TRACE("CSapR3Rfc::CSapR3Rfc() - Memory allocation error");<br />
}<br />
<br />
mode = trace = 0;<br />
}<br />
<br />
CSapR3Rfc(RFC_OPTIONS* m_opt)<br />
{<br />
try {<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
}<br />
catch(...) {<br />
TRACE("CSapR3Rfc::CSapR3Rfc() - Memory allocation error");<br />
}<br />
<br />
CSapR3Rfc(CSapR3Rfc& __sapr3rfc)<br />
{<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
<br />
mode = trace = 0;<br />
}<br />
<br />
~CSapR3Rfc(void)<br />
{<br />
delete [] cphostname;<br />
delete [] cpclient; <br />
}
System generate folowing message when processing the delete operator.
------------------------------------------------------------------
The thread 'Win32 Thread' (0x56c) has exited with code 2 (0x2).
The thread 'Win32 Thread' (0x964) has exited with code 2 (0x2).
Detected memory leaks!
Dumping objects ->
{74} normal block at 0x003457B8, 4 bytes long.
Data: < > CD CD CD CD
{73} normal block at 0x00345768, 17 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[2416] smc_server.exe' has exited with code 0 (0x0).
The program '[2416] smc_server.exe: Native' has exited with code 2 (0x2).
Ahmet Orkun GEDiK
Technical Consultant
ASTRON Project Office
|
|
|
|