Ich konnte eine Zeichenfolge zurückgeben, indem Sie im Speicher erstellen und übergeben Sie einfach einen Zeiger und die Größe der Zeichenfolge an Python. Ich habe eine example project erstellt, in der ich einige Funktionen getestet habe, um Werte zurückzugeben, bevor ich sie implementiert habe: Im folgenden Beispiel habe ich ein String-Array zurückgegeben. Ich habe einige Änderungen vorgenommen, um das Q anzupassen, damit ich irgendwo einen Fehler gemacht habe.
C#:
[DllExport]
static void StringArrayExample(out IntPtr unmanagedArray, out int length)//for ref value you have to use out
{
var valueList = new[]
{
"aaa", "bbb", "ccc"
};
length = valueList.Length;//return the length of the array
IntPtr[] ArrayPtr = new IntPtr[valueList.Length];
for (int i = 0; i < valueList.Length; i++)//create list of string arrays and
{
byte[] chars = System.Text.Encoding.ASCII.GetBytes(valueList[i] + '\0');//convert string to byte array
ArrayPtr[i] = Marshal.AllocHGlobal(chars.Length * Marshal.SizeOf(typeof(char)));//allocate memory to char array, return ptr to location
Marshal.Copy(chars, 0, ArrayPtr[i], chars.Length);//copy char array to memory location
}
//Create memory location to store pointers
unmanagedArray = Marshal.AllocHGlobal(valueList.Length * Marshal.SizeOf(typeof(IntPtr)));
//copy over all pointer to memory location
Marshal.Copy(ArrayPtr, 0, unmanagedArray, ArrayPtr.Length);
}
und die Python-Funktion Diese Funktion aufzurufen: Klasse Arrays ist die Datenstruktur, die ich für ein String-Array verwendet.
Cdll = ctypes.WinDLL("CtypesExamples.dll")
class Arrays(ctypes.Structure):# 2 string arrays
_fields_ = [ ('arr1', ctypes.POINTER(ctypes.c_char_p)),
('size1', ctypes.c_int),
('arr2', ctypes.POINTER(ctypes.c_char_p)),
('size2', ctypes.c_int)]
def StringArray(self, dllfunc, stringlist):
unmanagedArray = ctypes.POINTER(ctypes.c_char_p)()#create ctypes pointer
length = ctypes.POINTER(ctypes.c_int)()#create ctypes int
#call function with the ctypes pointer and int as ref
dllfunc(ctypes.byref(unmanagedArray), ctypes.byref(length))
INTP = ctypes.POINTER(ctypes.c_int)#pointer to int
addr = ctypes.addressof(length)#memory address of int
arraylength = ctypes.cast(addr, INTP)[0]#cast the pointer to int to a python variable
for i in range(0,arraylength):
stringlist.append(ctypes.string_at(unmanagedArray[i]).decode(encoding='UTF-8'))#decode convert from bits to string
return arraylength
#send list to c# dll
stringlist =list()
arraylength = self.StringArray(Cdll.StringArrayExample, stringlist)
print(str(arraylength)+" "+str(stringlist[0])+" "+str(stringlist[1])+" "+str(stringlist[2]))