如何从C++传递一个对象列表到C#?

7

我在这里的第一个问题 :)

我正在使用C++编写的应用程序(游戏地图编辑器),它的前端UI是用C#编写的。由于我对C#很陌生,所以我尽可能多地在C++方面进行操作。

我想从C#中调用一个返回简单变量类型(int和string)结构体列表的C++函数,以便我可以在UI中使用listBox来填充它们。这个可能吗?我应该如何在C#中编写dll导入函数?

我已经尝试搜索答案,但我只找到了有关如何将列表从C#传递到C++的帖子。

C++代码:

struct PropData
{
PropData( const std::string aName, const int aId )
{
    myName = aName;
    myID = aId;
}

std::string myName;
int myID;
};

extern "C" _declspec(dllexport) std::vector<PropData> _stdcall GetPropData()
{
std::vector<PropData> myProps;

myProps.push_back( PropData("Bush", 0) );
myProps.push_back( PropData("Tree", 1) );
myProps.push_back( PropData("Rock", 2) );
myProps.push_back( PropData("Shroom", 3) );

return myProps;
}

C#导入函数:
    [DllImport("MapEditor.dll")]
    static extern ??? GetPropData();

编辑:

在 Ed S. 的帖子之后,我将 C++ 代码更改为 struct PropData { PropData(const std::string aName, const int aId) { myName = aName; myID = aId; }

    std::string myName;
    int myID;
};

extern "C" _declspec(dllexport) PropData* _stdcall GetPropData()
{
    std::vector<PropData> myProps;

    myProps.push_back( PropData("Bush", 0) );
    myProps.push_back( PropData("Tree", 1) );
    myProps.push_back( PropData("Rock", 2) );
    myProps.push_back( PropData("Shroom", 3) );

    return &myProps[0];
}

并且C#中需要使用以下代码来调用:

[DllImport("MapEditor.dll")]
static extern PropData GetPropData();

    struct PropData
    {
        string myName;
        int myID;
    }

    private void GetPropDataFromEditor()
    {
        List<PropData> myProps = GetPropData();
    }

当然,这段代码无法编译,因为GetPropData()没有返回任何可以转换为列表的内容。
非常感谢Ed S.让我有了这么多进展!
1个回答

9
你无法将std::vector传递到C#领域中,你应该返回一个数组。在处理交互操作时,坚持使用基本类型会使事情更加简单。std::vector保证了&v[0]指向第一个元素,并且所有元素都是连续存储的,所以只需将数组传回即可。如果你被困在当前的C++接口中(我认为你不是),你需要研究一些更复杂的机制,比如COM。

他不能使用结构体吗?当然,用一种语言完成所有事情会更容易。如果前端是用C#编写的,那么完全可以在C#中完成所有事情。 - Security Hound
谢谢你的快速回答,但是我需要更多有关 C# 语法的帮助,如我所说,我是这门语言的新手(今天才开始学习),我甚至不知道它可以处理指针。 - Cousken
@Ramhound:我不认为你能够创建一个能够精确模仿 std::vector 的 C# 结构体,这仅适用于 POD 类型。 - Ed S.
@Cousken:问题在于您正在使用“PropData”对象填充向量,因此您还需要模仿这些对象。您应该能够创建一个结构体来模拟它。 Pinvoke.net 在这里是一个很棒的资源。 - Ed S.
@Ed S.:我可以将PropData对象拆分为int和string数组,将字符串拆分为char数组...今天上班时我会尝试这样做。或者,我可以将该列表导出到XML,然后在我的C#用户界面中读取它。 - Cousken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接