markshancock
markshancock

Reputation: 690

How do I return a managed string from a C++/CLI class

I am creating a C++/CLI class to package an auto-generated .h file so its values can be accessed from C#

Sample.h contains (auto-generated, can't change it)

#define NiFpga_M_OTRM_OVDFPGA_Bitfile "NiFpga_M_OTRM_OVDFPGA.lvbitx"
static const char* const NiFpga_M_OTRM_OVDFPGA_Signature = "D0751ADE3A0EC976606D63C425B35E85";

I created a C++/CLI class as follows

#include "Sample.h"

using namespace System;
using namespace Platform;
public ref class Sample
{
public:
    static System::String^ GetFilename() { return new System::String(NiFpga_M_OTRM_OVDFPGA_Bitfile);};
    static System::String^ GetSignature() { return new System::String(NiFpga_M_OTRM_OVDFPGA_Signature);};
}

When I try to use it from C#:

string bitfileName = Sample.GetFilename();
string signature = Sample.GetSignature();

I Get: "Pointers and fixed size buffers may only be used in an unsafe context"

I thought by doing the new I was creating a managed string

Upvotes: 0

Views: 3619

Answers (3)

David Yaw
David Yaw

Reputation: 27894

When I compile your code in VS 2012, I get two errors:

  • The class is named Sample, but the C# code is referencing it as OTRM_Ovd_FPGA.
  • error C2750: 'System::String' : cannot use 'new' on the reference type; use 'gcnew' instead.

Once I corrected the class name and replaced new with gcnew, both the C++/CLI and C# code worked fine.

I do have one suggestion with your code:

return gcnew System::String(NiFpga_M_OTRM_OVDFPGA_Bitfile);

The call to gcnew System::String is unnecessary. Since NiFpga_M_OTRM_OVDFPGA_Bitfile is a #define, the substitution is made by the preprocessor. The C++/CLI compiler knows how to deal with quoted strings as a String^, so you can just do return NiFpga_M_OTRM_OVDFPGA_Bitfile;, same as you could do return "foo"; in a method that returned String^. Calling gcnew System::String results in an unnecessary copy of the string to be constructed.

Upvotes: 3

Karthik Kalyanasundaram
Karthik Kalyanasundaram

Reputation: 1525

try gcnew System::String() instead..

To create instance of managed classes we should use gcnew.

Upvotes: 3

Thraka
Thraka

Reputation: 2174

Remove the ^ from your declaration

System::String^

Becomes

System::String

I believe that ^ means a managed pointer.

Upvotes: 0

Related Questions