Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one have Python receive a variable-length string array from C#?

This may be a red herring, but my non-array version looks like this:

C#

using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace Blah
{
    public static class Program
    {
        [DllExport("printstring", CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.AnsiBStr)]
        public static string PrintString()
        {
            return "Hello world";
        }
    }
}

Python

import ctypes
dll = ctypes.cdll.LoadLibrary(“test.dll")
dll.printstring.restype = ctypes.c_char_p
dll.printstring()

I am looking for a printstrings, which would fetch a List<string> of variable size. If that's not possible, I will settle for a fixed-length string[].

like image 826
Dimitri Shvorob Avatar asked Jan 22 '18 19:01

Dimitri Shvorob


1 Answers

.NET is capable of transforming the object type into COM Automation's VARIANT and the reverse, when going through the p/invoke layer.

VARIANT is declared in python's automation.py that comes with comtypes.

What's cool with the VARIANT is it's a wrapper that can hold many things, including arrays of many things.

With that in mind, you can declare you .NET C# code like this:

[DllExport("printstrings", CallingConvention = CallingConvention.Cdecl)]
public static void PrintStrings(ref object obj)
{
    obj = new string[] { "hello", "world" };
}

And use it like this in python:

import ctypes
from ctypes import *
from comtypes.automation import VARIANT

dll = ctypes.cdll.LoadLibrary("test")
dll.printstrings.argtypes = [POINTER(VARIANT)]
v = VARIANT()
dll.printstrings(v)
for x in v.value:
  print(x)
like image 89
Simon Mourier Avatar answered Nov 01 '22 03:11

Simon Mourier