Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling existing C++ code with /clr and then calling it from C#

I have some C++ code:

namespace Compute {
  class __declspec(dllexport) IProgressCB {
  public:
    virtual void progress(int percentCompleted) = 0;
  };

  double __declspec(dllexport) compute(IProgressCB *progressCB, ...);
}

from which I create "compute.dll" with "Common Language Runtime Support (/clr)" turned on in Visual Studio 2008.

I want to call this code from C#.

Next I create a C# console application and add compute.dll as a Reference. Then I try to subclass/implement IProgressCB:

public class Progress : Compute.IProgressCB
{
    public void progress(int percentCompleted)
    {
        Console.WriteLine(percentCompleted + "% completed.");
    }
}

However the autocompletion of VS finds the "Compute" namespace but not any classes or functions inside it!? When I try to compile; it complains about IProgressCB not being public. If I write public before the declaration of IProgressCB it complains about not being able to derive from sealed type 'Compute.IProgressCB' instead.

What am I doing wrong here? I want to take existing C++ code, do no modifications to it, but compile it with /clrc and then use it from C#. Is this not possible?

like image 546
Andy Avatar asked Jun 24 '11 12:06

Andy


People also ask

What does C++/CLI stand for?

C++/CLI is variant of the C++ programming language, modified for Common Language Infrastructure.

What is the difference between C++ and C++/CLI?

C++ runs directly as binary complied for your hardware. C++ cli is a c++ extension that is used to interface with the MS common language runtime. It complies to IL normally and is executed inside the . net runtime.

How do I enable CLR in Visual Studio?

In the Visual Studio IDE, the /clr compiler option can be individually set on the Configuration Properties > C/C++ > General page of the Property Pages dialog.


2 Answers

The "do no modifications" to it is possible, but you'll need an intermediary C++/CLI layer to wrap the existing code. C# and other CLR languages can only "see" managed types, that is ref classes, value classes etc. You'll not be able to get away with writing no additional C++ code simply by applying /clr to an extant codebase.

like image 183
Logan Capaldo Avatar answered Oct 10 '22 20:10

Logan Capaldo


IProgressCB has to be a managed class to be visible from C#.

public ref class IProgressCB
{
    // ...
};  

Doing this, IProgressCB will work quite differently than it did before, especially the memory management is now completely different.

You can use C++/CLI to write managed wrappers for your existing unmanaged classes, but don't expect that you can use unmanaged C++ classes from C# directly just by adding "/clr" to your compiler switches. Read this article

http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx

to get a notion what you have to do to transfer data from one world to the other and vice versa.

like image 28
Doc Brown Avatar answered Oct 10 '22 20:10

Doc Brown