Mixed Mode Adapter for Native C++


 

So our customer's goal was to update their native C++ application with support for calling a static instance of a C# class and share that instance with native and managed clients from within the same process space. This is a sample created to demonstrate one method to accomplish this task. (Many thanks to Rodney Viana for helping solve several critical problems I ran into making this sample work (if you have not downloaded Rodney's debugging extension - what are you waiting for? http://netext.codeplex.com/)

We chose a mixed C++/CLI adapter as a solution:

Visual C++ supports the use of the Standard C++ Library, the Common RunTime library (CRT), ATL, and MFC for applications compiled with /clr (Common Language Runtime Compilation). This allows existing applications that use these libraries to use .NET Framework features as well. From <https://msdn.microsoft.com/en-us/library/ms173268.aspx>

Solution contains three projects (Link to Visual Studio Solution: http://1drv.ms/1A45F7Q):

  1. shared_object - C# Class project (.Net 4.5.1)
  2. mixedAdapter - C++ CLR project
  3. client - C++ Win32

 

shared_object

This DLL exposes a simple singleton class with one method named Hello_World. It returns a string to the caller.

 

mixedAdapter

This is the C++ CLR project which acts as an adapter or wrapper. It can been called from C++ natively and it can add managed references. I have a project reference to shared_object. Make sure to add this to your class __declspec(dllexport) so your client project can import later:

   1: #include <msclr\marshal_cppstd.h>
   2:  
   3: #include <string>
   4:  
   5: using namespace System; 
   6:  
   7: using namespace shared_object;
   8:  
   9: #pragma native
  10:  
  11: namespace mixedAdapter 
  12:  
  13: {
  14:  
  15: class __declspec(dllexport) InTheMix
  16:  
  17: {
  18:  
  19: public:
  20:  
  21: std::string SayHello()
  22:  
  23: {
  24:  
  25: SingletonObj^ instance = SingletonObj::GetInstance();
  26:  
  27: std::string returnValue = msclr::interop::marshal_as<std::string>(instance->Hello_World());
  28:  
  29: return returnValue;
  30:  
  31: }
  32:  
  33: };
  34:  
  35: }
  36:  

client

Client has a header file with __declspec(dllimport) to import the definition from the lib file

   1: #include <string>
   2:  
   3: namespace mixedAdapter
   4:  
   5: {
   6:  
   7: class __declspec(dllimport) InTheMix
   8:  
   9: {
  10:  
  11: public:
  12:  
  13: std::string SayHello();
  14:  
  15: };
  16:  
  17: }
  18:  

And the client.cpp file has #pragma comment (lib,"mixedAdapter") added which is a hint to the linker to find the correct lib file. To get this working, I opened to project properties of client, under Linker, I selected "Additional Library Directories" and put in the path of my mixedAdapter.lib file. Without this step you may get a complier error.

   1: #include "stdafx.h"
   2:  
   3: #include "mixedAdapter.h"
   4:  
   5: using namespace mixedAdapter;
   6:  
   7: #pragma comment (lib,"mixedAdapter")
   8:  
   9: int _tmain(int argc, _TCHAR* argv[])
  10:  
  11: {
  12:  
  13: std::string str;
  14:  
  15: InTheMix myClass;
  16:  
  17: str = myClass.SayHello();
  18:  
  19: printf("%s", str.c_str());
  20:  
  21: return 0;
  22:  
  23: }
  24:  

 

Test:

C:\Visual Studio 2013\Projects\mixedAdapter\Debug>client.exe

Hello World

Comments (2)

  1. Indul Hassan says:

    Yes, this test was successful. Thanks for the post.

  2. Indul Hassan says:

    Thanks

Skip to main content