【问题标题】:Can one have Python send a variable-length string array to C#?可以让 Python 向 C# 发送一个可变长度的字符串数组吗?
【发布时间】:2018-06-14 21:39:55
【问题描述】:

这是this question 的倒数/补码。

我正在使用Unmanaged Exportsctypes,并且想将可变长度的字符串列表从 Python 传递到 C#,并返回一个字符串。

我尝试了四个 C# + Python 变体 - 没有一个成功。任何人都可以完成这项工作吗?

C#

    /* no ref, convert to list */
    [DllExport("combineWords1", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.AnsiBStr)]
    public static string CombineWords1(object obj)
    {
        var l = (List<string>) obj;
        return string.Join(",", l.ToArray());
    }

    /* no ref, convert to array */
    [DllExport("combineWords2", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.AnsiBStr)]
    public static string CombineWords2(object obj)
    {
        var l = (string[]) obj;
        return string.Join(",", l);
    }

    /* ref, convert to list */
    [DllExport("combineWords3", CallingConvention = CallingConvention.Cdecl)]
    public static void CombineWords3(ref object obj)
    {
        var l = (List<string>)obj;
        obj = string.Join(",", l.ToArray());
    }

    /* ref, convert to array */
    [DllExport("combineWords4", CallingConvention = CallingConvention.Cdecl)]
    public static void CombineWords4(ref object obj)
    {
        var l = (string[]) obj;
        obj = string.Join(",", l.ToArray());
    }

Python

import ctypes
from comtypes.automation import VARIANT

dll = ctypes.cdll.LoadLibrary("<...>")
l = ["Hello", "world"]

# 1 
dll.combineWords1.argtypes = [ctypes.POINTER(VARIANT)]
dll.combineWords1.restype = ctypes.c_char_p
obj = VARIANT(l)
dll.combineWords1(obj)
#WindowsError: [Error -532462766] Windows Error 0xE0434352

# 2
dll.combineWords2.argtypes = [ctypes.POINTER(VARIANT)]
dll.combineWords2.restype = ctypes.c_char_p
obj = VARIANT(l)
dll.combineWords2(obj)
# WindowsError: [Error -532462766] Windows Error 0xE0434352

# 3
dll.combineWords3.argtypes = [ctypes.POINTER(VARIANT)]
obj = VARIANT(l)
dll.combineWords3(obj)
#WindowsError: [Error -532462766] Windows Error 0xE0434352

# 4
dll.combineWords4.argtypes = [ctypes.POINTER(VARIANT)]
obj = VARIANT(l)
dll.combineWords4(obj)
#WindowsError: [Error -532462766] Windows Error 0xE0434352      

【问题讨论】:

    标签: c# python dll ctypes unmanagedexports


    【解决方案1】:

    您可以像这样声明 C# 端:

    [DllExport("combinewords", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.LPWStr)] // matches python's c_wchar_p
    public static string CombineWords(object obj) // object matches python's VARIANT
    {
        var array = (object[])obj; // if obj is an array, it will always be an array of object
        return string.Join(", ", array);
    }
    

    而python方面是这样的:

    import ctypes
    from ctypes import *
    from comtypes.automation import VARIANT
    
    dll = ctypes.cdll.LoadLibrary("exported") # the dll's name
    dll.combinewords.argtypes = [VARIANT] # python VARIANT = C# object
    dll.combinewords.restype = ctypes.c_wchar_p
    
    # create a VARIANT from a python array
    v = VARIANT(["hello", "world"])
    print(dll.combinewords(v))  
    

    注意:我使用了更好的 unicode 声明。 Ansi 已成为过去。

    【讨论】:

      猜你喜欢
      • 2018-07-01
      • 2021-11-02
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 2021-04-26
      相关资源
      最近更新 更多