Python для. NET: передача списка функций от <dynamic>до C# - PullRequest
1 голос
/ 13 апреля 2020

Я пытаюсь вызвать из python code C# функции из dll, используя Python для. NET. Большинство вещей работали из коробки, или я мог бы понять их из других сообщений (например, передавая IntPtr из массива ниже), но последнее, что отказывается работать, - это передать список в качестве параметра.

Вот функция C#

bool CalculateResult(string resultName, IntPtr resultArray, IList <dynamic> AuxParameters = null)

и ее использование в примере C# фрагмент кода:

CalculateResult("xyz", ptr, new List<dynamic> { 50 });

I выполнить вызов функции из python БЕЗ необязательного 3-го параметра:

clr.AddReference('SDK')
import SDK_Namespace
from System import Array, Int16, IntPtr, String
from System.Runtime.InteropServices import GCHandle, GCHandleType

pyArr = [0] * 100
csArr = Array[Int16](pyArr )
arr_hndl = GCHandle.Alloc(csArr, GCHandleType.Pinned)
ptr_arr = arr_hndl.AddrOfPinnedObject()
CalculateResult(result, ptr_arr)
# pyArr has now values, yay!

Теперь, если я попытаюсь сделать то же самое С дополнительным параметром списка, я потерплю неудачу, что бы я ни пытался:

from System.Collections.Generic import List

pyList = [50]
CalculateResult(result, ptr_arr, pyList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, pyList)
# TypeError: No match found for signature

csList = List[Int16]()
csList.Add(50)
CalculateResult(result, ptr_arr, csList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, csList)
# TypeError: No match found for signature

Чего мне не хватает и как я могу заставить это работать?

Редактировать

После комментария Йероена и чтения упаковки и распаковки Я смог запустить функцию C#, как показано ниже:

from System import Object
par = int(50)
csList = List[Object]()
csList.Add(Object(par))
CalculateResult(result, ptr_arr, csList)

Теперь функция вызвала исключение без особых намеков на отладку.

Однако другая функция GetInfo(string resultName, IList <dynamic> AuxParameters = null) с аналогичными аргументами было бы более полезно рассказать мне:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type
'object' to 'int'. An explicit conversion exists (are you missing a cast?)
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at SDK.GetInfo(String ResultName, IList`1 Parameters)

Как я не могу изменить что-то на стороне C#, где, как я подозреваю, должна произойти распаковка, вопрос меняется на:

Могу ли я что-то еще сделать для «явного преобразования», или я должен отказаться?

1 Ответ

0 голосов
/ 14 апреля 2020

Не уверен, что это работает в вашем случае, но я смог позвонить, используя это в Python (с Python для. NET добавочный номер):

xl = List[Object]()
xl.Add(50)
b = d.CalculateResult("resultName", ptr_arr, xl)

объект, который отображается в методе C#, имеет тип Int32, что, вероятно, является ожидаемым.

Я реализовал метод теста с той же сигнатурой, что и у вас, вот что я использовал:

public bool CalculateResult(string resultName, IntPtr resultArray, IList<dynamic> AuxParameters = null)
{
    if (AuxParameters != null)
    {
        dynamic a = AuxParameters.First();
        Console.WriteLine(" *Type: " + ((object)a).GetType().Name);
        foreach (var m in ((object)a).GetType().GetMembers())
        {
            Console.WriteLine(" " + m.Name);
        }
        Console.WriteLine(a);
    }
    return true;
}
...