英文:
Marshalling variable-sized string C array into C# (Unity iOS)
问题
我需要将Objective-C中的字符串集合返回给C#,但我无法理解如何正确地完成这个任务。当我在托管端打印返回的指针时,它的值为0。
Objective-C部分代码如下:
FOUNDATION_EXPORT int _GetAllKeys(char** pointer)
{
NSArray* array = @[@"key1", @"key2"]; // 虚拟字符串
int size = (int)array.count;
pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
pointer[i] = MakeStringCopy(array[i]);
}
return size;
}
C#部分代码如下:
[DllImport("__Internal")]
private static extern int _GetAllKeys(out IntPtr buffer);
internal static IEnumerable<string> GetAllKeys()
{
int count = _GetAllKeys(out var buffer);
List<string> keys = new List<string>();
for (int i = 0; i < count; i++)
{
keys.Add(Marshal.PtrToStringUTF8(IntPtr.Add(buffer, IntPtr.Size))); // 最终当我解决这个问题时,字符串将以UTF8返回,但现在它甚至没有到达这一行,所以忽略编码。
}
return keys;
}
---------------- 解决方案 ----------------
Objective-C部分代码如下:
FOUNDATION_EXPORT int _GetAllKeys(char*** pointer)
{
NSArray* array = @[@"key1", @"key2"];
int size = (int)array.count;
*pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
(*pointer)[i] = MakeStringCopy(array[i]);
}
return size;
}
C#部分代码如下:
[DllImport("__Internal")]
private static extern int _GetAllKeys(out IntPtr buffer);
internal static IEnumerable<string> GetAllKeys()
{
int count = _GetAllKeys(out var buffer);
List<string> keys = new List<string>();
for (int i = 0; i < count; i++)
{
IntPtr ptr = Marshal.ReadIntPtr(buffer);
keys.Add(Marshal.PtrToStringAuto(ptr));
buffer = IntPtr.Add(buffer, IntPtr.Size);
}
return keys;
}
英文:
I need to return a collection of strings from Objective-C to C# and can't wrap my head around how to do this properly. When I print the returned pointer on managed side its value is 0.
Objective-c
FOUNDATION_EXPORT int _GetAllKeys(char** pointer)
{
NSArray* array = @[@"key1", @"key2"]; // dummy strings
int size = (int)array.count;
pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
pointer[i] = MakeStringCopy(array[i]);
}
return size;
}
C#
[DllImport("__Internal")]
private static extern int _GetAllKeys(out IntPtr buffer);
internal static IEnumerable<string> GetAllKeys()
{
int count = _GetAllKeys(out var buffer);
List<string> keys = new List<string>();
for (int i = 0; i < count; i++)
{
keys.Add(Marshal.PtrToStringUTF8(IntPtr.Add(buffer, IntPtr.Size))); //eventually when i make this work the strings will be returned as UTF8 but for now its not even making it to this line, so ignore the encoding.
}
return keys;
}
---------------- SOLUTION ----------------
Objective-c
FOUNDATION_EXPORT int _GetAllKeys(char*** pointer)
{
NSArray* array = @[@"key1", @"key2"];
int size = (int)array.count;
*pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
(*pointer)[i] = MakeStringCopy(array[i]);
}
return size;
}
C#
[DllImport("__Internal")]
private static extern int _GetAllKeys(out IntPtr buffer);
internal static IEnumerable<string> GetAllKeys()
{
int count = _GetAllKeys(out var buffer);
List<string> keys = new List<string>();
for (int i = 0; i < count; i++)
{
IntPtr ptr = Marshal.ReadIntPtr(buffer);
keys.Add(Marshal.PtrToStringAuto(ptr));
buffer = IntPtr.Add(buffer, IntPtr.Size);
}
return keys;
}
答案1
得分: 1
你正在尝试返回一个char**,所以C函数的参数需要是char***:
FOUNDATION_EXPORT int _GetAllKeys(char*** pointer)
{
NSArray* array = @[@"key1", @"key2"]; // dummy strings
int size = (int)array.count;
*pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
(*pointer)[i] = MakeStringCopy(array[i]);
}
return size;
}
C#代码看起来没问题,只是IntPtr.Add返回一个新的IntPtr,所以它应该是:
keys.Add(Marshal.PtrToStringUTF8(buffer));
buffer = IntPtr.Add(buffer, IntPtr.Size);
英文:
You are trying to return a char**, so the C function parameter needs to be a char***:
FOUNDATION_EXPORT int _GetAllKeys(char*** pointer)
{
NSArray* array = @[@"key1", @"key2"]; // dummy strings
int size = (int)array.count;
*pointer = malloc(size * sizeof(char *));
for (int i = 0; i < size; i++)
{
(*pointer)[i] = MakeStringCopy(array[i]);
}
return size;
}
The C# code looks fine, except that IntPtr.Add returns a new IntPtr, so it has to be:
keys.Add(Marshal.PtrToStringUTF8(buffer));
buffer = IntPtr.Add(buffer, IntPtr.Size);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论