I am trying to pinvoke to a function with the following signature:
const char ** SWDLLEXPORT org_crosswire_sword_SWModule_parseKeyList(SWHANDLE hSWModule, const char *keyText);
This returns an array of string.
I have example usage of this from c
const char **results = org_crosswire_sword_SWModule_parseKeyList(module, argv[2]);
while (results && *results) {
printf("%s\n", *results);
++results;
}
The pinvoke I have tried is as follows:
[DllImport(DLLNAME)]
public static extern IntPtr org_crosswire_sword_SWModule_parseKeyList(IntPtr hSWModule, string keyText);
And code to use it:
public IEnumerable<string> ParseKeyList(string keyText)
{
IntPtr keyListPtrs = NativeMethods.org_crosswire_sword_SWModule_parseKeyList(_handle, keyText);
return NativeMethods.MarshalStringArray(keyListPtrs);
}
public static IEnumerable<string> MarshalStringArray(IntPtr arrayPtr)
{
IntPtr ptr = Marshal.ReadIntPtr(arrayPtr);
while(arrayPtr != IntPtr.Zero && ptr != IntPtr.Zero)
{
ptr = Marshal.ReadIntPtr(arrayPtr);
string key = Marshal.PtrToStringAnsi(ptr);
yield return key;
arrayPtr = new IntPtr(arrayPtr.ToInt64() + 1);
}
}
This works for the first item and segfaults for the second on the PtrToStringAnsi line. What am I doing wrong, and what is the correct way to pinvoke to this function.
arrayPtrby 1 which shifts it 1 byte. But you want to make it point to the next array element, so you should addIntPtr.Size.