P/使用 LibraryImport 调用,字节数组及其输入/输出长度属性编组问题

问题描述 投票:0回答:0

我有一个用旧的

[DllImport]
定义的函数如下,它工作得很好

[DllImport("tbs.dll", EntryPoint = "Tbsip_Submit_Command", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern uint Tbsip_Submit_Command(
 IntPtr context,
 uint locality,
 uint priority,
 [In] byte[] inBuffer,
 uint inBufferSize,
 [Out] byte[] outbuf,
 ref uint outBufLen
);

我想将此定义转换为使用

LibraryImport
的源代码生成方式。但是,我遇到了
outBuf
outBufLen
的问题。

[LibraryImport("tbs", EntryPoint = "Tbsip_Submit_Command",StringMarshalling = StringMarshalling.Utf16)]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvStdcall) })]
internal static partial uint Tbsip_Submit_Command(
    IntPtr context,
    uint locality,
    uint priority,
    in byte[] inBuffer,
    uint inbufferSize,
    out byte[] outbuf,
    ref uint outBufLen
);

我认为错误消息相当描述了应该做什么。但我不知道如何以及是否“如何”是正确的做法。

错误 SYSLIB1051 将数组从非托管编组到托管需要在“MarshalAsAttribute”上设置“SizeParamIndex”或“SizeConst”字段,或者在“MarshalUsingAttribute”上设置“ConstantElementCount”或“CountElementName”属性。生成的源不会处理参数“outbuf”

的编组

但是如果我尝试类似的东西

[LibraryImport("tbs", EntryPoint = "Tbsip_Submit_Command",StringMarshalling = StringMarshalling.Utf16)]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvStdcall) })]
internal static partial uint Tbsip_Submit_Command(
    IntPtr context,
    uint locality,
    uint priority,
    in byte[] inBuffer,
    uint inbufferSize,
    [MarshalUsing(CountElementName = "outBufLen")] out byte[] outbuf,
    ref uint outBufLen
);

编译器停止抱怨。但是,调用不起作用,因为编组器抛出

System.ArgumentException: '目的地太短。 (参数'目的地')'

有没有人知道如何处理这种进出情况?目的或

òutBufLen
都是为了告诉传入缓冲区长度,然后作为返回值将多少字节写入缓冲区。

c# .net pinvoke
© www.soinside.com 2019 - 2024. All rights reserved.