c# - 在不知道数组大小的情况下从 C 到 C# P/Invoke

标签 c# arrays pinvoke unsafe

正确地知道在我的代码中我有这样声明的结构,并修复了这个 16,在编译时就知道了。

struct CONSOLE_SCREEN_BUFFER_INFOEX
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public int ColorTable[];
}

但我需要的是能够拥有这样的结构:

struct CONSOLE_SCREEN_BUFFER_INFOEX
{
   int arraySize;
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
   public int ColorTable[];
}

从 C 函数响应中获取 arraySize,用适当的大小初始化 ColorTable 数组,将响应结果放入 ColorTable。

不确定是否可能,现在正在调查,非常欢迎任何评论。

最佳答案

您可以使用 Marshal 类进行一些手动编码,轻松地完成此操作。例如:

[DllImport(@"MyLib.dll")]
private static extern void Foo(IntPtr structPtr);

private static IntPtr StructPtrFromColorTable(int[] colorTable)
{
    int size = sizeof(int) + colorTable.Length*sizeof(int);
    IntPtr structPtr = Marshal.AllocHGlobal(size);
    Marshal.WriteInt32(structPtr, colorTable.Length);
    Marshal.Copy(colorTable, 0, structPtr + sizeof(int), colorTable.Length);
    return structPtr;
}

private static int[] ColorTableFromStructPtr(IntPtr structPtr)
{
    int len = Marshal.ReadInt32(structPtr);
    int[] result = new int[len];
    Marshal.Copy(structPtr + sizeof(int), result, 0, len);
    return result;
}

static void Main(string[] args)
{
    int[] colorTable = new int[] { 1, 2, 3 };
    IntPtr structPtr = StructPtrFromColorTable(colorTable);
    try
    {
        Foo(structPtr);
        colorTable = ColorTableFromStructPtr(structPtr);
    }
    finally
    {
        Marshal.FreeHGlobal(structPtr);
    }
}

关于c# - 在不知道数组大小的情况下从 C 到 C# P/Invoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18491000/

相关文章:

C#/VB .Net 性能调优,生成所有可能的彩票组合

C# If Equals 不区分大小写

c# - 转换 Nullable DateTime 时,LINQ to Entities 无法识别方法 'System.String ToString()' 方法

javascript - 类型-/JavaScript - array.indexOf 始终返回 -1

c - 使用 malloc 的指针时出现奇怪的内存分配

c# - Dll导入不完整的名称

c# - 调用 native 函数时最后一个参数出现损坏

c# - 在linux上用c代码调用c#代码的最佳方法是什么

javascript - 使用嵌套对象内的键/值对对象数组进行排序

c# - 用于复杂方法调用的 PInvoke C#