在C#中使用具有另一个C ++类对象的C ++类

时间:2013-06-10 02:38:17

标签: c# c++ interop marshalling

我为自己创建了一个小程序来练习结合C ++和... C#(对我来说非常理想的技能) 它看起来像这样:

Class Diagram

问题产生于班级Person的成员类型为Name
将这些类暴露给C#的正确方法是什么?

例如,我将如何公开这个构造函数:

    Person(Name name);

这很难解释,但问题是这个Person构造函数接受一个本地的Name对象,我无法在C#中创建这个本机对象,只是将其传递给构造函数,对吗?这甚至都不可取 即使我为它编写了一个包装器(比如ManagedName),我也无法将它传递给Person,因为没有可接受的构造函数。

我应该如何应对这种情况?

以下是请求的标题:

Nullable:http://pastebin.com/z7zTCrAq
姓名:http://pastebin.com/ALNp5c1a
人:http://pastebin.com/nkWyUv9C

1 个答案:

答案 0 :(得分:1)

这是一种方法(C ++ / CLI)


class Name {
public:
    std::string firstName;
    std::string middleName;
    std::string lastName;
};
ref class ManagedName {
internal:
    Name* nameptr;
public:

    ManagedName() {
        nameptr = new Name();
    }
    ManagedName(System::IntPtr ptr) {
        nameptr = (Name*)(void*)ptr;
    }
    property System::String^ firstName {
        System::String^ get() {
            return gcnew System::String(nameptr->firstName.data());
        }
        void set(System::String^ val) {
            System::IntPtr strptr = System::Runtime::InteropServices::Marshal::StringToBSTR(val);
            nameptr->firstName = (char*)(void*)strptr;
            System::Runtime::InteropServices::Marshal::FreeBSTR(strptr);
        }
    };
    property System::String^ middleName {
        System::String^ get() {
            return gcnew System::String(nameptr->middleName.data());
        }
        void set(System::String^ val) {
            System::IntPtr strptr = System::Runtime::InteropServices::Marshal::StringToBSTR(val);
            nameptr->middleName = (char*)(void*)strptr;
            System::Runtime::InteropServices::Marshal::FreeBSTR(strptr);
        }
    };
    property System::String^ lastName {
        System::String^ get() {
            return gcnew System::String(nameptr->lastName.data());
        }
        void set(System::String^ val) {
            System::IntPtr strptr = System::Runtime::InteropServices::Marshal::StringToBSTR(val);
            nameptr->lastName = (char*)(void*)strptr;
            System::Runtime::InteropServices::Marshal::FreeBSTR(strptr);
        }
    };
};
class Person {
public:
    Name* name;
    std::string birthday;
    Person(Name* name) {
        this->name = name;
    }
};
ref class ManagedPerson {
public:
    ManagedPerson(ManagedName^ name) {
        //create an instance of the native class
        personPtr = new Person(name->nameptr);

    }
    property System::String^ Birthday {
        System::String^ get() {
            return gcnew System::String(personPtr->birthday.data());
        }

    };
    property ManagedName^ Name {
        ManagedName^ get() {
            return gcnew ManagedName(System::IntPtr(personPtr->name));
        }
    };
private:
    Person* personPtr;
};