C#:结构的马歇尔数组,带有来自C+的字符串+/目标C与C统一#

C#:结构的马歇尔数组,带有来自C+的字符串+/目标C与C统一#,c#,c++,objective-c,unity3d,marshalling,C#,C++,Objective C,Unity3d,Marshalling,我试图将ObjectiveC/C++创建的带有字符串的结构数组封装到C#中,但没有成功。大多数情况下,C#编组无法找到“value”字符串字段。这是迄今为止我得到的最好的: C#结构: C#代码 在这一点上我很迷茫,我尝试了不同的组合。我还尝试了两个字符串的IntPtr结构,但我确定“value”指针为0 有什么想法吗?我发现了问题所在。我的问题是如何创建/读取结构数组。在最初的C#实现中,预期给定的数组是指向结构的指针数组,但本机代码使用结构本身创建了一个数组 这个问题可以用两种不同的方法来解

我试图将ObjectiveC/C++创建的带有字符串的结构数组封装到C#中,但没有成功。大多数情况下,C#编组无法找到“value”字符串字段。这是迄今为止我得到的最好的:

C#结构:

C#代码

在这一点上我很迷茫,我尝试了不同的组合。我还尝试了两个字符串的IntPtr结构,但我确定“value”指针为0


有什么想法吗?

我发现了问题所在。我的问题是如何创建/读取结构数组。在最初的C#实现中,预期给定的数组是指向结构的指针数组,但本机代码使用结构本身创建了一个数组

这个问题可以用两种不同的方法来解决。更新C++代码,创建指向结构的指针数组:

void getEntries(NSDictionary* dictionary, Entry** &_entries, int &size) {
    int count = (int) [dictionary count];

    // Array of pointers! Structs will be malloc-ed individually on the loop.
    Entry** entries = (Entry**) malloc(count * sizeof(Entry*) );

    int i = 0;
    for(id key in dictionary) {
        id value = [dictionary objectForKey:key];

        // It creates a pointer to the struct
        entries[i] = (Entry*) malloc(sizeof(Entry));

        entries[i]->key = Utils::mallocCharStr(key);
        entries[i]->value = Utils::mallocCharStr(value);

        ++i;
    }

    _entries = entries;
    size = count;
}
C#的处理方式是:

public Dictionary<string, string> Convert()
{
    var dic = new Dictionary<string, string>();

    getEntries(NativeInstance, out IntPtr pUnmanagedArray, out int keysCount);

    IntPtr[] pIntPtrArray = new IntPtr[keysCount];

    // This was the original problem.
    // Now it copies the native array pointers to individual IntPtr. Which now they point to individual structs.
    Marshal.Copy(pUnmanagedArray, pIntPtrArray, 0, keysCount);

    for (int i = 0; i < keysCount; i++)
    {
        Entry entry = Marshal.PtrToStructure<Entry>(pIntPtrArray[i]); // Magic!
        dic.Add(entry.Key, entry.Value);

        Marshal.FreeHGlobal(pIntPtrArray[i]); // Free the individual struct malloc
    }

    Marshal.FreeHGlobal(pUnmanagedArray); // Free native array of pointers malloc.

    return dic;
}
公共字典转换()
{
var dic=新字典();
getEntries(NativeInstance、out IntPtr pUnmanagedArray、out int key count);
IntPtr[]pIntPtrArray=新的IntPtr[keysCount];
//这是最初的问题。
//现在,它将本机数组指针复制到各个IntPtr。现在它们指向各个结构。
Marshal.Copy(pUnmanagedArray,pIntPtrArray,0,keycount);
对于(int i=0;i
==

另一个可能的解决方法是保持C++在原问题上的方式。因此,这意味着本机代码将创建一个结构数组(而不是指针)。但随后需要更新C#代码,以正确偏移数组中的每个项

public Dictionary<string, string> Convert()
{
    var dic = new Dictionary<string, string>();

    getEntries(NativeInstance, out IntPtr pUnmanagedArray, out int keysCount);

    // Note that we don't use Marshal.Copy(...).
    // Every item in the array has an memory offset of the size of the struct, rather than the size of the pointer to a struct.

    for (int i = 0; i < keysCount; i++)
    {
        // "Selects" the nth structure by offseting the original pointer element:
        IntPtr pCurrent = pUnmanagedArray + i * Marshal.SizeOf(typeof(Entry));

        Entry entry = Marshal.PtrToStructure<Entry>(pCurrent);

        dic.Add(entry.Key, entry.Value);
    }

    // It only frees the array of struct itself because it contains the structs themselves.
    Marshal.FreeHGlobal(pUnmanagedArray);

    return dic;
}
公共字典转换()
{
var dic=新字典();
getEntries(NativeInstance、out IntPtr pUnmanagedArray、out int key count);
//注意,我们不使用Marshal.Copy(…)。
//数组中的每个项都有一个结构大小的内存偏移量,而不是指向结构的指针大小。
对于(int i=0;i

请注意,在执行自动逻辑封送处理时,结构的字符串会自动释放。

我发现了这个问题。我的问题是如何创建/读取结构数组。在最初的C#实现中,预期给定的数组是指向结构的指针数组,但本机代码使用结构本身创建了一个数组

这个问题可以用两种不同的方法来解决。更新C++代码,创建指向结构的指针数组:

void getEntries(NSDictionary* dictionary, Entry** &_entries, int &size) {
    int count = (int) [dictionary count];

    // Array of pointers! Structs will be malloc-ed individually on the loop.
    Entry** entries = (Entry**) malloc(count * sizeof(Entry*) );

    int i = 0;
    for(id key in dictionary) {
        id value = [dictionary objectForKey:key];

        // It creates a pointer to the struct
        entries[i] = (Entry*) malloc(sizeof(Entry));

        entries[i]->key = Utils::mallocCharStr(key);
        entries[i]->value = Utils::mallocCharStr(value);

        ++i;
    }

    _entries = entries;
    size = count;
}
C#的处理方式是:

public Dictionary<string, string> Convert()
{
    var dic = new Dictionary<string, string>();

    getEntries(NativeInstance, out IntPtr pUnmanagedArray, out int keysCount);

    IntPtr[] pIntPtrArray = new IntPtr[keysCount];

    // This was the original problem.
    // Now it copies the native array pointers to individual IntPtr. Which now they point to individual structs.
    Marshal.Copy(pUnmanagedArray, pIntPtrArray, 0, keysCount);

    for (int i = 0; i < keysCount; i++)
    {
        Entry entry = Marshal.PtrToStructure<Entry>(pIntPtrArray[i]); // Magic!
        dic.Add(entry.Key, entry.Value);

        Marshal.FreeHGlobal(pIntPtrArray[i]); // Free the individual struct malloc
    }

    Marshal.FreeHGlobal(pUnmanagedArray); // Free native array of pointers malloc.

    return dic;
}
公共字典转换()
{
var dic=新字典();
getEntries(NativeInstance、out IntPtr pUnmanagedArray、out int key count);
IntPtr[]pIntPtrArray=新的IntPtr[keysCount];
//这是最初的问题。
//现在,它将本机数组指针复制到各个IntPtr。现在它们指向各个结构。
Marshal.Copy(pUnmanagedArray,pIntPtrArray,0,keycount);
对于(int i=0;i
==

另一个可能的解决方法是保持C++在原问题上的方式。因此,这意味着本机代码将创建一个结构数组(而不是指针)。但随后需要更新C#代码,以正确偏移数组中的每个项

public Dictionary<string, string> Convert()
{
    var dic = new Dictionary<string, string>();

    getEntries(NativeInstance, out IntPtr pUnmanagedArray, out int keysCount);

    // Note that we don't use Marshal.Copy(...).
    // Every item in the array has an memory offset of the size of the struct, rather than the size of the pointer to a struct.

    for (int i = 0; i < keysCount; i++)
    {
        // "Selects" the nth structure by offseting the original pointer element:
        IntPtr pCurrent = pUnmanagedArray + i * Marshal.SizeOf(typeof(Entry));

        Entry entry = Marshal.PtrToStructure<Entry>(pCurrent);

        dic.Add(entry.Key, entry.Value);
    }

    // It only frees the array of struct itself because it contains the structs themselves.
    Marshal.FreeHGlobal(pUnmanagedArray);

    return dic;
}
公共字典转换()
{
var dic=新字典();
getEntries(NativeInstance、out IntPtr pUnmanagedArray、out int key count);
//注意,我们不使用Marshal.Copy(…)。
//数组中的每个项都有一个结构大小的内存偏移量,而不是指向结构的指针大小。
对于(int i=0;i

请注意,在执行automagic封送处理时,结构的字符串会自动释放。

unity版本是什么?最新版本。那么2019.3.你的unity版本是什么?最新版本。因此,2019.3.我想知道是否有Marshal.Copy()的替代方法来创建给定偏移量而不是默认指针大小的数组。我想知道是否有Marshal.Copy()的替代方法来创建给定偏移量而不是默认指针大小的数组。