Pinvoke 如何封送这个嵌套的指针,并在C中使用C结构#

Pinvoke 如何封送这个嵌套的指针,并在C中使用C结构#,pinvoke,Pinvoke,现在我需要在C#中为上面的C函数做包装 我应该如何封送PT_INPUT_BIR*结构,以及在返回此函数后如何将其解组 请帮我解决这个问题 /**********************有关此问题的更多详细信息**************************/ C结构和函数在上面进行了定义。请参考这里 C#结构: 对于C#struct声明,我为一个C结构维护了两个结构。bcz一个用于设置值,另一个id用于传递给c函数 PT_STATUS StoreFinger ( IN PT_CONNECTI

现在我需要在C#中为上面的C函数做包装

我应该如何封送PT_INPUT_BIR*结构,以及在返回此函数后如何将其解组

请帮我解决这个问题

/**********************有关此问题的更多详细信息**************************/

  • C结构和函数在上面进行了定义。请参考这里

  • C#结构:

  • 对于C#struct声明,我为一个C结构维护了两个结构。bcz一个用于设置值,另一个id用于传递给c函数

    PT_STATUS StoreFinger (
    IN PT_CONNECTION hConnection,
    IN PT_INPUT_BIR *pTemplate,
    OUT PT_LONG *plSlotNr
    )
    
    最后,在调用C fun()之前,我将把值从C#app struct复制到wrapper struct

    2a)C#应用程序端代码为:

    C# app struct:
    
    [StructLayout(LayoutKind.Sequential)]//for app
        public struct FPINPUTBIR
        {
            public byte byForm;
            public InputBIRType InputBIR;       
        }
        [StructLayout(LayoutKind.Sequential)] // here when i use explicit it throws exception so i         removed it.
        public struct InputBIRType
        {
           // [FieldOffset(0)]
            public FPBIR pBIR;
            //[FieldOffset(0)]
            public int lSlotNr;
            //[FieldOffset(0)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] abyReserved;
        }
    
         C# wrapper struct:
    
    [StructLayout(LayoutKind.Sequential)]
        public struct FP_INPUTBIR
        {
            public byte byForm;
            public IntPtr mIPBIR;
        }
    
        [StructLayout(LayoutKind.Explicit, Size = 20, CharSet = CharSet.Ansi)]
        public struct Input_BIRType
        {
            [FieldOffset(0)]
            public IntPtr mBIR;
            [FieldOffset(0)]
            public int lSlotNr;
            //[FieldOffset(8)]
            //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            //public byte[] abyReserved;
        }
    
    C#包装侧:

     //here mAppMemory is already known value
    
     FPINPUTBIR lfipdata = new FPINPUTBIR();
                FPDATA lfpdata = new FPDATA();    
    
                    lfipdata.byForm = (byte)eFPVerifyBy.FULLBIR_INPUT;
                    lfipdata.InputBIR = new InputBIRType();
                    lfipdata.InputBIR.abyReserved = new byte[20];
                    lfipdata.InputBIR.pBIR.Data = new        byte[mAppMemory[listBox2.SelectedIndex].Header.Length];
                    Array.Copy(mAppMemory[listBox2.SelectedIndex].Data, lfipdata.InputBIR.pBIR.Data, mAppMemory[listBox2.SelectedIndex].Header.Length);
                    lfipdata.InputBIR.pBIR.Header = mAppMemory[listBox2.SelectedIndex].Header;
    
                     Verify(ref lfipdata); //calling from C# APP side to C# wrapper
    
    问题:

  • 我真的需要两个C#结构吗
  • 我应该在C#包装器函数中做什么。请记住,我有两个C#struct,具有不同的成员

  • 谢谢。

    您只需要对上一个问题中使用的
    PT\u BIR
    进行一点扩展。在那里,我们将可变长度结构编组为
    byte[]
    。您可以使用相同的代码来生成字节数组,我将不再重复

    接下来你需要工会。即:

    public int Verify(ref FPINPUTBIR apStoredTemplate )
            {
               // i passed the args (apStoredTemplate ) but throws exception struct mismatch with C struct.
    
                //here i don't know what should i do. 
    
               CDLL.StoreFinger(..,ref apStoredTemplate,.. );  //pls refer the C function above
            }
    
    无需声明工会的保留部分。这个尺寸可以解决这个问题

    然后
    PT\u INPUT\u BIR

    [StructLayout(LayoutKind.Explicit, Size = 20)]
    public struct PT_INPUT_BIR_UNION
    {
        [FieldOffset(0)]
        public IntPtr pBIR; 
        [FieldOffset(0)]
        public int lSlotNr; // I'm guessing what PT_LONG is
    }
    
    然后需要使用
    GCHandle
    固定
    PT\u BIR
    字节数组。让我们保持与该问题相同的命名,并假设
    PT_-BIR
    保存在名为
    data
    byte[]
    变量中

    [StructLayout(LayoutKind.Sequential)]
    public struct PT_INPUT_BIR
    {
        Byte byForm;
        PT_INPUT_BIR_UNION InputBirUnion;
    }
    

    当您声明
    StoreFinger
    时,
    PT\u-BIR*
    参数应声明为
    ref-PT\u-BIR

    它是一个fugly-mother,PT\u-BIR是一个可变长度的结构,没有提示“Data”可能意味着什么。还完全不清楚为结构分配的内存是否需要在调用后保持有效。咬合对对齐非常重要。在C++/CLI包装器中执行此操作从来都不是一个坏主意。结合您在最近的其他问题中了解到的内容,它看起来与其他任何联合都非常相似。嗨,David,我的疑问是如何解组结果输出。你能在这里发布示例代码吗。那能帮我解决这个问题吗?谢谢。你在忙什么?这看起来很像你以前的帖子。我也同意汉斯的观点。使用C++/CLI对您来说会更容易。嗨,David,这对我来说很有用。谢谢你抽出时间。
    [StructLayout(LayoutKind.Sequential)]
    public struct PT_INPUT_BIR
    {
        Byte byForm;
        PT_INPUT_BIR_UNION InputBirUnion;
    }
    
    GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 
    try
    {
        PT_INPUT_BIR inputBir;
        inputBir.byForm := ...;
        inputBir.InputBirUnion.pBIR = handle.AddrOfPinnedObject();
        // now call StoreFinger passing ref inputBir
    }
    finally
    {
        handle.Free();
    }