0

You can create a VC++ Windows Forms project that runs on the CLR, which is essentially a .NET app written in C++. Can you use unmanaged C++ libraries directly from such a project? Does that mean that the library must compile and run under .NET? Or must you write CLR wrapper classes for such libraries and only those will be usable from the CLR app?

Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607

2 Answers2

1

Yes. Here are some guides. Mixing CLI/C++ and native code. You don't need a wrapper to use them in CLI/C++. In fact, you use CLI/C++ and native code to create a wrapper.

http://www.technical-recipes.com/2012/mixing-managed-and-native-types-in-c-cli/

http://www.codeproject.com/Articles/35041/Mixing-NET-and-native-code

If you are actually trying to make a wrapper to use in C#, it should look something like this:

#include "NativeClass.h"

public ref class NativeClassWrapper {
    NativeClass* m_nativeClass;

public:
    NativeClassWrapper() { m_nativeClass = new NativeClass(); }
    ~NativeClassWrapper() { delete m_nativeClass; }
    void Method() {
        m_nativeClass->Method();
    }

protected:
    // an explicit Finalize() method—as a failsafe
    !NativeClassWrapper() { delete m_nativeClass; }
};

Refer to C++/CLI wrapper for native C++ to use as reference in C#

Community
  • 1
  • 1
corylulu
  • 3,449
  • 1
  • 19
  • 35
  • 1
    Yes, that's actually how you make wrappers. :] – corylulu Mar 19 '13 at 17:11
  • This is how to create a wrapper, but you don't need to if you are using it in C++. If you want to bring it to C#, then yes, this is what you need. I noticed you tagged C#, so maybe that's what you want to do. – corylulu Mar 19 '13 at 17:14
  • Better idea: Use a working smart pointer such as [this one I wrote](http://codereview.stackexchange.com/q/1695/2150) instead of duplicating the memory cleanup code in each wrapper class. For example, this answer has a memory leak. – Ben Voigt Mar 19 '13 at 17:19
  • 1
    @Geotarget: The above code didn't include a finalizer, so if you forget to call `Dispose()` it will leak. Or if you call `Dispose()` more than once (yes, that's legal in .NET) bad things will happen. Just replace `NativeClass* m_nativeClass;` with `clr_scoped_ptr m_nativeClass;` and the compiler will then correctly generate the destructor and finalizer for you. – Ben Voigt Mar 19 '13 at 17:25
  • 1
    @Geotarget and BenVoigt I would personally stick to the simple method of creating wrappers until you get a better grip on the subject, but bookmark Bens answer for when you want to optimize your solution. This is the basics of creating a wrapper. But yes, those are the steps you need. Create a new CLI/C++ project and include the library and compile it as a DLL. Then import the DLL and copy the original library to your new C# project. – corylulu Mar 19 '13 at 17:26
  • @Geotarget I just added the finalizer. – corylulu Mar 19 '13 at 17:28
  • @Corylulu: Now bad things (double-delete) happen if you do call `Dispose`. Why not use a solution that already works? – Ben Voigt Mar 19 '13 at 17:32
  • @Corylulu - I used a modified version of yours. Thanks again!! – Robin Rodricks Mar 24 '13 at 18:16
  • @Corylulu Is it possible to create an unmanaged **.CPP** file without a library? I'm used to unmanaged C++, so my solution was a library (unmanaged) with some code to update the UI as needed. **Is this possible?** Thanks. – Anonymous Penguin Oct 06 '13 at 00:01
1

Using a smart pointer library makes it much simpler to manage allocation of native (not garbage collected) objects, which is surprisingly difficult in the presence of exceptions, multiple calls to Dispose(), forgetting to call Dispose(), etc.

Here's Dr_Asik's example, rewritten to use a smart pointer I wrote:

#include "clr_scoped_ptr.h"
#include "NativeClass.h"

public ref class NativeClassWrapper {
    clr_scoped_ptr<NativeClass> m_nativeClass;

public:
    NativeClassWrapper() m_nativeClass(new NativeClass()) {}
    // auto-generated destructor is correct
    // auto-generated finalizer is correct

    void Method() {
        m_nativeClass->Method();
    }
};

For string conversions, use the marshal_as class Microsoft provided for the purpose. Check out ildjarn's answer here: C++/CLI String Conversions

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Thanks for your well informed answer, Ben, I'm accepting it until someone comes up with a better answer. You seem to be a C++ pro judging by your SO rep on the matter (gold C++ badge, how many people have those?!) so I trust that you know exactly what you're talking about here. Constrast that with myself, a beginner. Well.. someday! – Robin Rodricks Mar 19 '13 at 17:34
  • @Geotarget: SO rep and badges aren't the most reliable indicator, but I like to think I give good answers. Keep practicing and you'll develop expertise as well. – Ben Voigt Mar 19 '13 at 17:35
  • Can you tell me a bit about converting C# data types to C++ and back? Just the basics for strings and ints/doubles. I've got some reference code here for strings: http://www.codeproject.com/Articles/35041/Mixing-NET-and-native-code but everything is still pretty flaky. – Robin Rodricks Mar 19 '13 at 17:35