How to import and use a unmanaged C++ class from C

2019-05-21 19:02发布

I have an native C++ dll, some header files and the import library. Is there a way how to instantiate an object within C# that is defined in the dll?

The two ways I'm aware of are:

  1. to wrap the C++ code into COM
  2. to use DLLImport and external C functions

2条回答
狗以群分
2楼-- · 2019-05-21 19:24

I think that your option is only build a C++/CLI class wrapper (so you can reference it like a c# class), otherwise you can't instantiate a c++ class (unmanaged) from c# code.

Alternative could be the "ugly" way: instantiate the c++ class through a c function, but you'll treat the class as a void pointer inside the c# code, so you basically will not do anything with it (except if you create other functions to interact with this class; only C functions)

C# understands C, if you want make it understand C++ you have to use C++/CLI

P.S. C# has some basic understanding of C++ classes, but it's only about converting class data (I mean bytes: fields) into some usable data in C# (there are some Attributes), but will not allow to work with methods and things like that (avoid totally is my suggestion).

查看更多
可以哭但决不认输i
3楼-- · 2019-05-21 19:37

C++/CLI is your friend for this. You'll run into one problem though: it is not possible to store standard C++ objects inside C++/CLI ref or value classes (the ones for .NET). So you'll have to resort to the following class (that you can modify) that I use in production code:

#pragma once
#include <boost/shared_ptr.hpp>

template <typename T>
ref class Handle
{
    boost::shared_ptr<T>* t;

    !Handle() 
    {
        if (t != nullptr)
        {
            delete t;
            t = nullptr;
        }
    }

    ~Handle() { this->!Handle(); }

public:
    Handle() : t(new boost::shared_ptr<T>((T*)0)) {}

    Handle% operator=(T* p)
    {
        if (p != t->get()) t->reset(p);
        return *this;
    }

    static T* operator&(Handle% h) { return h.t->get(); }
    static boost::shared_ptr<T> operator->(Handle% h) { return *h.t; }

    T& reference() { return *t->get(); }
    T const& const_reference() { return *t->get(); }
};

Usage: Handle<MyCppClass>^ handle; inside a C++/CLI class. You then implement stub methods, forwarding them to the handle member. Garbage collected objects will call destructors of the C++ class instance iff there is no more pointer to it:

public ref class Foo
{
    void bar() { handle->bar(); }

internal:
    Handle<CppNamespace::Foo>^ handle;
};
查看更多
登录 后发表回答