{"record":{"id":"aedec4dd579082a2","repo":"JeffreySu/WeiXinMPSDK","slug":"finance-sdk-buffername-length-msgauditfinancenativeapi","errorCode":null,"errorMessage":"Finance SDK 返回的 {bufferName} 指针为空，但长度为 {length}。","messagePattern":"Finance SDK 返回的 (.+?) 指针为空，但长度为 (.+?)。","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs","lineNumber":260,"sourceCode":"            var bytes = ReadBytes(pointer, length, bufferName);\n            return bytes.Length == 0 ? string.Empty : Encoding.UTF8.GetString(bytes);\n        }\n\n        private static byte[] ReadBytes(IntPtr pointer, int length, string bufferName)\n        {\n            if (length < 0)\n            {\n                throw new InvalidOperationException($\"Finance SDK 返回了无效的 {bufferName} 长度：{length}。\");\n            }\n\n            if (length == 0)\n            {\n                return Array.Empty<byte>();\n            }\n\n            if (pointer == IntPtr.Zero)\n            {\n                throw new InvalidOperationException($\"Finance SDK 返回的 {bufferName} 指针为空，但长度为 {length}。\");\n            }\n\n            var bytes = new byte[length];\n            Marshal.Copy(pointer, bytes, 0, length);\n            return bytes;\n        }\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        private delegate IntPtr NewSdkDelegate();\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        private delegate int InitDelegate(IntPtr sdk, IntPtr corpId, IntPtr secret);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        private delegate void DestroySdkDelegate(IntPtr sdk);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        private delegate IntPtr NewSliceDelegate();","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs#L242-L278","documentation":"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.","triggerScenarios":"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.","commonSituations":"Wrong-architecture native library causing field misalignment; SDK failure return code ignored before reading; reading MediaData from a previous aborted download.","solutions":["Check the return code of GetMediaData (must be 0) before reading buffers.","Confirm the loaded SDK bitness matches the process; field misalignment is the usual cause.","Discard the MediaData and re-request the media file with a new MediaData object.","Log the SDK error code and retry with a longer timeoutSeconds."],"exampleFix":"// before\nvar bytes = financeApi.GetMediaBytes(mediaData); // throws on null pointer + nonzero len\n// after\nvar ret = GetMediaDataWithRetry(mediaData);\nif (ret == 0 && financeApi.IsMediaDataFinished(mediaData))\n{\n    var bytes = financeApi.GetMediaBytes(mediaData);\n}","handlingStrategy":"validation","validationCode":"int len = GetDataLen(mediaData);\nif (len > 0 && GetData(mediaData) == IntPtr.Zero) throw new InvalidOperationException(\"null buffer with nonzero length\");","typeGuard":"static bool IsReadable(IntPtr ptr, int len) => len > 0 && ptr != IntPtr.Zero;","tryCatchPattern":"try { var bytes = api.GetMediaBytes(mediaData); }\ncatch (InvalidOperationException ex) { logger.LogWarning(ex, \"Inconsistent MediaData, will re-download\"); return await DownloadMediaAsync(fileId); }","preventionTips":["Verify IsMediaDataFinished before reading.","Don't ignore GetMediaData return codes.","Use a matching-architecture official SDK build."],"tags":["native-interop","finance-sdk","null-pointer"],"backgroundTag":"null-argument","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}