如何使用list <pair <tstring,tstring>&gt;作为C#中C ++函数的参数

时间:2016-02-01 20:58:47

标签: c# dll

我获得了一个C ++库,其函数带有list&lt;的参数。对&LT; tstring,tstring&gt;&gt;。 我需要为其他开发人员创建一个C#shim才能使用这个库。

我知道不允许编组泛型类型,所以我想知道我是否可以传入一个模仿C ++中对的列表的结构数组。

为了测试这是否有效,我制作了一个简单的C ++ DLL,它模仿我给出的DLL。我在C ++ Test DLL中创建了以下函数:

//In my C++ Test DLL
int MyFunction(list<pair<tstring, tstring>> &listParams)

在C#中,我创建了以下结构来模仿这对tstrings:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
struct myPair
{
    [MarshalAs(UnmanagedType.LPTStr)]
    public string Key;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string Value;

    public myPair(string key, string val)
    {
        Key = key;
        Value = val;
    }
}

这也是我的C ++函数的PInvoke定义:

[System.Runtime.InteropServices.DllImport("MyTestLib.dll",  
CharSet = CharSet.Unicode, EntryPoint = "MyFunction")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern Int32 MyFunction(
        [param:  MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
        ref myPair[] listParams);

以下是我的C#Test Shim中的代码:

    public Int32 MyFunctionTest(Dictionary<string, string> testData)
    {
        Int32 retCode = 0;

        try
        {
            List<myPair> transfer = new List<myPair>();

            foreach (var entry in testData)
            {
                transfer.Add(new myPair(entry.Key, entry.Value));
            }

            myPair[] transferArray = transfer.ToArray();

            retCode = NativeMethods.MyFunction(ref transferArray);

        }
        catch (Exception ex)
        {
        }
        return retCode;
    }

虽然调用成功(不会崩溃),但在我的C ++方法中,数据是乱码且无效。

有没有人知道这种映射是否可行?

1 个答案:

答案 0 :(得分:1)

感谢Wimmel,我找到了答案。这是为了创建一个基于CLR的Shim&#34;这是我的C#和C ++库之间的桥梁。

以下是代码:

//This is a method in a shim class which takes the C# objects
//and translates them to the C++ types required in the C++ dll 
Int32 myClass::Method(Dictionary<System::String^, System::String^> ^args)
{
    Int32 retCode = 0;
    list<pair<wstring, wstring>> listParams;

    for each (KeyValuePair<String^, String^>^ kvp in args)
    {
        listParams.insert(listParams.end(), 
            make_pair(msclr::interop::marshal_as<wstring>(kvp->Key),
            msclr::interop::marshal_as<wstring>(kvp->Value))
                          );
    }

    //My C++ Method
    MyFunction(listParams);

    return retCode;
}

我在我的C ++库中对此进行了测试,传入的数据正确无误地进行了