Question

I've never worked with either C++ or C++/CLI, but I would like to use a native C++ library in a C# project. I googled a bit, learnt a few things about C++/CLI and decided to give it a head start. But I'm not sure if I'm doing any of it right.

I have the following struct in a native namespace:

avcodec.h

typedef struct AVCodecDescriptor {
    enum AVCodecID     id;
    enum AVMediaType type;

    const char      *name;
    const char *long_name;
    int             props;
} AVCodecDescriptor;

Now I want to wrap this struct in C++/CLI for using it in C#:

public ref struct AVCodecDescriptorWrapper {

    private:
        struct AVCodecDescriptor *_avCodecDescriptor;

    public:
        AVCodecDescriptorWrapper() {
            _avCodecDescriptor = new AVCodecDescriptor();
        }
        ~AVCodecDescriptorWrapper() {
            delete _avCodecDescriptor;
        }

        // what do?
        property AVCodecID Id {
            AVCodecID get() {
                return; // what comes here ????
            }
        }

};

However, it seems like I'm doing something horribly wrong since I'm not even able to see the fields of the struct AVCodecDescriptor in C++/CLI. Do I have to wrap the enums in the struct to? Do I have to copy them into C++/CLI and cast it (well, enum AVCodecID has like 350 values - a copy/paste seems ridiculus.)

Was it helpful?

Solution

You need to create a equivalent CLI class of native struct and Enums.

public ref class ManagedAVCodecDescriptor {
    ManagedAVCodecIDClass id;
    ManagedAVMediaTypeClass type;

    String^ name;
    String^ long_name;
    int props;
};

Enum equivalent class will look like this:

public enum class ManagedAVCodecIDClass
{
    xyx = 1,
    abc = 2,
    ...
}

Now in your AVCodecDescriptorWrapper you should get AVCodecDescriptor object and put all information in the ManagedAVCodecDescriptor object and pass it to C# class.

ManagedAVCodecDescriptor^ mObject = gcnew ManagedAVCodecDescriptor();
mObject.setSomeValue(nativeStruct->somevalue);

and pass mObject to C# code as general C# object.

OTHER TIPS

I prefer to use .NET structure within native code. You define:

public enum class AVCodecID : long
{
    mp4 = 1,
    mpeg2 = 2,
    ...

}

public ref class AVCodecDescriptor
{
    AVCodecID id,
    ...
    System::String name
    ...
}

and whenever you need in C++ code you will call

AVCodecDescriptor cd = gcnew AVCodecDescriptor();

It is not always handy, you need files using it compiled with /clr switch and sometimes you can get mad with converting managed/unmanaged strings, but many times this was quite suitable for me. Anyway you can use .NET enums quite easily in C++ native code, typing enum values to int.

Does this not work?

   property int Id {
        int get() {
            return _avCodecDescriptor->id;
        }
    }

BTW you should be using some smart pointer for lifetime management of the native object, as right now you will leak memory if the .NET object is finalizer instead of disposed. For an example, see my scoped_ptr for C++/CLI (ensure managed object properly frees owned native object)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top