返回

使用 IntPtr 编组结构以从 C# 缓冲到 C dll

发布时间:2022-07-12 13:36:57 237
# flask

我整天都在敲我的头,希望有人能帮忙。我需要将托管数据结构编组为非托管 C dll。当我查看所有内存时,似乎我正在做的事情正在工作,但是 C dll(对我来说是一个黑盒子)正在返回一个错误,表明数据已损坏。谁能指出我的错误?

C 声明

   typedef struct _TAG_Data
   {
       void *data;      // Binary data
       uint32_t size;   // Data size bytes
   } Data;
    
        
    // Parse binary data, extract int value
    ParseData(Data ∗ result, uint64_t parameter, int32_t ∗ value)

托管对象:

     public class MyData
    {
        public byte[] data;
        public UInt32 size;
    }

用于移动到非托管内存的压缩等价物:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyData_Packed
{
    public IntPtr data;
    public UInt32 size;
}

在这一点上,我有一个“管理”;我的数据“;已调用结构我的结果需要进入dll的有效数据。以下是我正在做的:

       [DllImport("Some.dll", EntryPoint = "ParseData", SetLastError = true, CharSet = CharSet.Ansi)]
       private static extern Int32 ParseData_Native(IntPtr result, UInt64 parameter, ref Int32 value);


        IntPtr MyResultPackedPtr = new IntPtr();
        MyData_Packed MyResultPacked = new MyData_Packed();

        // Copy "MyResult" into un-managed memory so it can be passed to the C library.  

        // Allocate un-managed memory for the data buffer
        MyResultPacked.data = Marshal.AllocHGlobal((int)MyResult.size);

        // Copy data from managed "MyResult.data" into the unmanaged "MyResultPacked.data"
        Marshal.Copy(MyResult.data, 0, MyResultPacked.data, (int)MyResult.size);
        MyResultPacked.size = MyResult.size;

        // Allocate unmanaged memory for the structure itself
        MyResultPackedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyData_Packed)));
        
        // Allocate unmanaged memory for the struct itself, 
        // copy the packed struct into the unmanaged memory and get our pointer
        Marshal.StructureToPtr(MyResultPacked, MyResultPackedPtr, false);

        // Pass our pointer to the unmanaged struct, which points to the unmanaged data buffer, to the C dll
        Int32 tmp = 0;
        ErrorCode = ParseData_Native(MyResultPackedPtr, parameter, ref tmp);

当我看到我的结果已打包。数据,数据正确,因此副本良好。当我看到我的结果已打包。数据(64位机器),接下来的4个字节是数据的适当大小。所以看起来MyResultPackagedPTR指向的有效副本我的结果已打包. 但返回值来自ParseData()表示我的数据一定已损坏,所以我一定做错了什么。

为了更进一步,我用C语言百分之百地编写了相同的代码,它可以正常工作。C中二进制缓冲区中的数据与C#中二进制缓冲区中的数据相匹配,符合Visual Studio中的内存监视功能,因此我的数据处理似乎是正确的。这让我觉得我的传球方式有问题MyResultPackagedPTR到dll。不幸的是,我没有dll的源代码,无法进入它。有人能提出下一步该做什么的建议吗?

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(1)
按点赞数排序
用户头像