Pass Data from C# to C++ in Visual Studio

Viewed 122

I'm trying to build a a simple C# application to test passing data between languages. I have a simple main in C# calling a function that I wish to pass to C++:

using System;

namespace CS_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            CPP_Sum(5, 2); //pseudo code
        }
    }
}

and then the function in a C++ project:

CPP_Sum(int x, int y)
{
    return x+y;
}

The problem is, I don't even know where to start on how to pass these between each other.

This is being done via two projects, CS_Console and CPP_Console, in the same solution in Visual Studio.

2 Answers

It has already been mentioned by @steveo314. The easiest way to call a C++-based function from C# is using PInvoke. I assume you can create a DLL without any documentation but this looks like it will give you all the information you need to use your DLL from C#. Basically:

  1. Put your function as a C++ DLL; then
  2. Use a DllImport attribute to create a function prototype in your C# code.

Make sure you export your C++ function definitions.

Daniel's answer above is also correct, but if you really want to dive into the guts of this, you may want to learn C++/CLI, as that's more or less C++ running on top of the .NET framework, with more precise interop, and depending on where/what your DLL is, communication both ways (P/Invoke is just calling C++, not calling back into .NET... usually).

C++/CLI allows this kind of thing:

public class Program
{
  public void main(String [] args)
  {
    NativeWrapper wrapper = new NativeWrapper(); // C++/CLI ref class
    wrapper.doStuff("hey there!");
  }
}

In a C++/CLI DLL, in the .h file:

// This is C++/CLI

class NativeClass; // Forward declare
ref class NativeWrapper
{
public:
  NativeWrapper();  // Constructor - MUST be in .cpp file, as size of NativeClass not known here
  ~NativeWrapper(); // Destructor - MUST be in .cpp file, same reason as above
  void doStuff(System::String^ inputString);
private:
  NativeClass* mp_impl;
};

In a C++/CLI .cpp file:

class NativeClass // True C++ class, could be defined elsewhere!
{
public:
  void nativeDoStuff(const std::string& inputString)
  {
    std::cout << "Previous input was: '" << cachedResult << "'";
    cachedResult = inputString;
  }
private:
  std::string cachedResult{};
};

NativeWrapper::NativeWrapper()
{
  mp_impl = new NativeClass();
}
NativeWrapper::~NativeWrapper()
{
  delete mp_impl;
  mp_impl = nullptr;
}
// Utility function!
std::string _convertClrString(System::String^ instr)
{
  marshal_context context;
  std::string mystring{ context.marshal_as<const char*>(instr) };
  return mystring;
}
void NativeWrapper::doStuff(System::String^ inputString)
{
  auto native_string = _convertClrString(inputString);
  mp_impl->nativeDoStuff(native_string);
}

It's a toy example (necessary includes removed), but hopefully that gets the idea across of what's possible with C++/CLI. The link I put near the top is the main start of the resources at Microsoft for doing this. Keep in mind what files are compiling as .NET, which aren't (you can do it per-file), and what that all means.

Related