0

I would like to use external C++ libraries in a .Net standard project. I have read something about p/invoke and unmanaged code so I started from something really simple. I created a simple C++ project, the following are the header file and related implementation:

Sum.h

#ifndef SUM_H_INCLUDED
#define SUM_H_INCLUDED

#ifdef _WIN32
# define EXPORTIT __declspec( dllexport )
#else
# define EXPORTIT
#endif

namespace Something
{
  namespace Really
  {
    namespace Simple
    {

      class SimpleClass
      {

      public:
        SimpleClass();
        double SumValues( double x, double y);
      };

  #pragma region Object handlers

      // create instance
      extern "C"
      {
        EXPORTIT SimpleClass* CreateInstance();
      }

      //Invoke Sum Method
      extern "C"
      {
        EXPORTIT double InvokeSumValues( SimpleClass*instance, double x, double y);
      }

      // Delete instance
      extern "C"
      {
        EXPORTIT void InstanceDelete(SimpleClass*instance);
      }
  #pragma endregion

    }
  }
}
#endif

Sum.cpp

#include "Sum.h"

using namespace Something::Really::Simple;

SimpleClass::SimpleClass()
{
  // empty constructor
}

double SimpleClass::SumValues(double x, double y) {
  return x + y;
}

#pragma region Class handlers

SimpleClass* CreateInstance()
{
  return new SimpleClass;
}

double InvokeSumValues(SimpleClass*inst, double x, double y )
{
  return inst->SumValues( x, y);
}

void InstanceDelete(SimpleClass*inst)
{
  delete inst;
}

#pragma endregion

If I try to build the project I get some

LNK2019 unresolved external symbol

The only way I found to solve that, is to move the methods implementation from the .cpp to the .h file, but I would like to keep the method definitions and the related implementation separated.

Basically my question is, how I get it to work?

Just for the sake of completeness, this is how I would invoke the C++ from the C# implementation:

[DllImport( @"Simple.dll", EntryPoint = "CreateInstance", CallingConvention = CallingConvention.Cdecl )]

private static extern IntPtr CreateInstance();

[DllImport( @"Simple.dll", EntryPoint = "InvokeSumValues", CallingConvention = CallingConvention.Cdecl )]

private static extern IntPtr InvokeSumValues(IntPtr inst, double x, double y);

private static void SumValues(double x, double y )
    {
        IntPtr inst = CreateInstance();
        InvokeSumValues( inst, x, y );
    }
fragae
  • 285
  • 1
  • 3
  • 9
  • `using namespace Something::Really::Simple;` doesn't put the rest of the file inside that namespace. So the function definitions will be in the global namespace, which is not what the linker is looking for. You either have to reopen the namespace or prefix each function name with its namespace. – Bo Persson May 29 '18 at 12:29
  • I just solved it enabling the Common Language Runtime Support in the Project Configuration Properties. https://msdn.microsoft.com/en-us/library/k8d11d4s.aspx – fragae May 30 '18 at 08:24

0 Answers0