using strcopy:  cannot convert parameter 2 from 'const System::String __gc *' to 'const char *'

Posted on 2003-03-21
Medium Priority
Last Modified: 2008-03-10

I am just learning OOP and C++.net.  I need to modify this code to make it
work.  Any help would be greatly appreciated!!!!!

// sends text to the controller, wait for response, return response
String * ODevice::SendAndGet( const String * Cmd ) const
   String * Response = "";

   if( hOms != NULL ) {          // if connected
      char resp[OMS_MAX_RESPONSE] = {'\0'}, cmd[OMS_MAX_RESPONSE] = {'\0'};
      strcpy( cmd, Cmd );        // dll takes only standard C types
      SendAndGetString( hOms, cmd, resp );
      Response->Format( "%s", resp );
   return( Response );

Here are the errors I receive:

test.cpp(74) : error C2664: 'strcpy' : cannot convert parameter 2 from 'const System::String __gc *' to 'const char *'  Cannot convert a managed type to an unmanaged type

test.cpp(76) : error C2664: 'System::String __gc *System::String::Format(System::String __gc *,System::Object __gc *)' : cannot convert parameter 2 from 'char [125]' to 'System::Object __gc *'  Cannot convert an unmanaged type to a managed type

This is at the top:

#using <mscorlib.dll>
using namespace System;

Here is the class definition for ODevice:

class ODevice  
     BYTE GetDone( void ) const;               // calls DLL function to get done flags
     void ClrDone( const BYTE );               // calls DLL function get clear done flags
     String * GetDrvrVrsn( void ) const;       // calls DLL function to get driver version
     String * SendAndGet( const String * ) const; // sends text to the controller and returns      controller's response
     void Disconnect( void );                  // disconnect from the controller
     void Connect( const String * );           // connect to the controller
     String * GetName( void ) const;           // returns the name of the current device

     ODevice();                                // standard constructor
     ~ODevice();                               // standard destructor

   HANDLE hOms;                                   // handle to the controller


Hopefully this is enough information.

Thanks in advance!

Question by:rreischl
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 46

Expert Comment

by:Kent Olsen
ID: 8182353
You're thinking in C. :)

Instead of strcpy(), just do:

cmd = Cmd;

These are classes and C++ will copy/convert the entire class object (struct) where C would not.

The same for the returned value:

Result = resp;

LVL 12

Accepted Solution

Salte earned 300 total points
ID: 8182469
a System::String __gc * is a .net string object. It simply isn't the same as const char.

System::String class has a function that let you read the char string though and you can use that function to extract the string data.

I can't recall what exactly that function is but if you look up in your help (F1 key) you'll find it easily. Search on the namespace System and the class String and then look for member functions.

Note that in C# the string data type is the basic data type while in C++ it is a class object System::String.

Your second error is kinda the opposite you try to convert an unmanaged type (char []) to a managed type.

I am afraid that you have run into the problems that most C++ programmers run into when they try .net. .Net can handle C++ in that you can write C++ code to it but there are severals but's in this:

1. The code tend to be clobbered with __gc and other non-standard C++ things, so the code is really more .Net than it is C++.

2. You constantly run into that it really is trying to do two worlds in one program - the .Net world and the traditional C++ world and they do not really merge very well.

I will therefore recommend you to look into C# and rather use C# for .Net stuff and rather stick to traditional unmanaged code in C++ - preferably standard ANSI C++ code in C++ :-)

However, if you still want to use C++.Net you must understnad that it really is two different worlds. System::Object, System::String etc etc etc are all so-called managed structures. There's a garbage collector handling them and they won't mix very well with non-managed code. There are some basic functions that let you extract the const char * data from a string etc and you can use those to convert but it is always a conversion, just mindlessly attempting a strcpy won't work.

The System::String class is defined in .Net.

Another thing is that the string class is a string of wchar_t elements and not char elements. Asssuming your code has only plain ASCII characters you can easily convert the two, in the general case you should rather let it stay wchar_t and not attempt any conversion.

Here is how you can strcpy a System::String to a char string:

char * string_copy(char * dst, size_t sz,
                   System::String __gc * src)
   int len = src -> get_Length();
   if (len + 1 > sz)
      return 0; // not enough room.

   for (int i = 0; i < len; ++i) {
      wchar_t wc = src -> get_Chars(i);
      if (wc < 0 || wc > 127)
         return 0; // couldn't translate.
      dst[i] = char(wc);
   dst[len] = '\0';
   return dst;

If you want to make it a wchar_t string you can do this:

wchar_t * string_copy(wchar_t * dst, size_t sz,
                      System::String __gc * src)
   int len = src -> get_Length();
   if ((len + 1)*sizeof(wchar_t) > sz)
      return 0; // not enough room.
   for (int i = 0; i < len; ++i)
      dst[i] = src -> get_Chars(i);
   dst[len] = L'\0';
   return dst;

Similarly for the other way you have to create an object out of the string, you cannot just pass that string as argument to Format. I believe the compiler is already able to automatically translate a char to a System::String pointer - at least it doesn't complain about the first format string you provide. But translating a string to System::Object is obviously something it cannot do on its own. You must help the compiler by doing:

System::String * p = new System::String(resp,strlen(resp));

Here I assume that resp is a null terminated string, if it isn't you must do something else and provide the length through some other way than strlen above.

Now you can call:

Response -> Format( "...", p );

Of course, you could do it in one call by doing:

Response -> Format( "...", new System::String(resp,strlen(resp)));

Hope this is of help.


LVL 11

Expert Comment

ID: 9543901
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered: Points to Salte

Please leave any comments here within the next seven days. Experts: Silence
means you don't care.


-bcl (bcladd)
EE Cleanup Volunteer

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question