我有一个用旧的
[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
都是为了告诉传入缓冲区长度,然后作为返回值将多少字节写入缓冲区。