JeffreySu/WeiXinMPSDK · error · InvalidOperationException

Finance SDK 返回的 指针为空,但长度为 。

Error message

Finance SDK 返回的 {bufferName} 指针为空,但长度为 {length}。

What it means

The Finance SDK returned a non-zero length for a buffer (e.g. MediaData.data or outindexbuf) but the buffer pointer itself is IntPtr.Zero. The wrapper refuses to Marshal.Copy from a null native pointer and throws InvalidOperationException naming the buffer. This indicates the native SDK returned an inconsistent MediaData struct.

Solutions

  1. Check the return code of GetMediaData (must be 0) before reading buffers.
  2. Confirm the loaded SDK bitness matches the process; field misalignment is the usual cause.
  3. Discard the MediaData and re-request the media file with a new MediaData object.
  4. Log the SDK error code and retry with a longer timeoutSeconds.

Example fix

// before
var bytes = financeApi.GetMediaBytes(mediaData); // throws on null pointer + nonzero len
// after
var ret = GetMediaDataWithRetry(mediaData);
if (ret == 0 && financeApi.IsMediaDataFinished(mediaData))
{
    var bytes = financeApi.GetMediaBytes(mediaData);
}
Defensive patterns

Strategy: validation

Validate before calling

int len = GetDataLen(mediaData);
if (len > 0 && GetData(mediaData) == IntPtr.Zero) throw new InvalidOperationException("null buffer with nonzero length");

Type guard

static bool IsReadable(IntPtr ptr, int len) => len > 0 && ptr != IntPtr.Zero;

Try / catch

try { var bytes = api.GetMediaBytes(mediaData); }
catch (InvalidOperationException ex) { logger.LogWarning(ex, "Inconsistent MediaData, will re-download"); return await DownloadMediaAsync(fileId); }

Prevention

When it happens

Trigger: GetMediaBytes(mediaData) or GetIndexBufBytes(mediaData) where the SDK set dataLen>0 but data pointer is null — typically after a failed or timed-out GetMediaData call, or a corrupted/ABI-mismatched MediaData struct.

Common situations: Wrong-architecture native library causing field misalignment; SDK failure return code ignored before reading; reading MediaData from a previous aborted download.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/aedec4dd579082a2. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs:260

            var bytes = ReadBytes(pointer, length, bufferName);
            return bytes.Length == 0 ? string.Empty : Encoding.UTF8.GetString(bytes);
        }

        private static byte[] ReadBytes(IntPtr pointer, int length, string bufferName)
        {
            if (length < 0)
            {
                throw new InvalidOperationException($"Finance SDK 返回了无效的 {bufferName} 长度:{length}。");
            }

            if (length == 0)
            {
                return Array.Empty<byte>();
            }

            if (pointer == IntPtr.Zero)
            {
                throw new InvalidOperationException($"Finance SDK 返回的 {bufferName} 指针为空,但长度为 {length}。");
            }

            var bytes = new byte[length];
            Marshal.Copy(pointer, bytes, 0, length);
            return bytes;
        }

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate IntPtr NewSdkDelegate();

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate int InitDelegate(IntPtr sdk, IntPtr corpId, IntPtr secret);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate void DestroySdkDelegate(IntPtr sdk);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate IntPtr NewSliceDelegate();

View on GitHub (pinned to be573f6f94)