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