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 wh开发者_运维技巧ich 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?
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.
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.
Clearly C++-CLI (the sucessor of Managed Extensions for C++) is not (like) C++. Visibilty of namespace members is only a small fraction of the difference.
The biggest trip up will be non-deterministic destruction of ref classes.
I suggest
- Read up on CLR assemblies first
- Don't think C++ anymore:
- Grok garbage collection
- Grok header dependencies, pImpl idom and gcroot<>
- Now, try a C++-CLI library from scratch to wrap a native library
After 1-2 years of[1]ample experience, you will be able to tell how much work it is to port a native C++ library 1:1 to C++-CLI
[1] -- ok maybe you are a fast learner :)
精彩评论