如何将指向C#struct的指针传递给C中的方法 我想在C++中使用C++ DLL。我正在使用[DllImport]调用该方法。我无法将struct传递给方法

如何将指向C#struct的指针传递给C中的方法 我想在C++中使用C++ DLL。我正在使用[DllImport]调用该方法。我无法将struct传递给方法,c#,c,pinvoke,C#,C,Pinvoke,我有一个C结构: typedef struct { DWORD TopPoint; DWORD EndPoint; WORD dwCount; MYFUNC_NUMERIC11 *pGetData; } MYFUNC_BUFFERNORMAL; MYFUNC\u NYMERIC11是另一个结构 typedef struct { BYTE Sign; // Sign ("±") BYTE Integer[3]; // 3-digit integer (no zero supp

我有一个C结构:

typedef struct
{
DWORD TopPoint;
DWORD EndPoint;
WORD dwCount;
MYFUNC_NUMERIC11 *pGetData;
} MYFUNC_BUFFERNORMAL;
MYFUNC\u NYMERIC11
是另一个结构

typedef struct
{
BYTE Sign; // Sign ("±")
BYTE Integer[3]; // 3-digit integer (no zero suppression)
BYTE Period; // Decimal point (".")
BYTE Decimal[6]; // 6-digit decimal number
} MYFUNC_NUMERIC11;
我编写了一个C#struct来模拟这一点

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public unsafe struct MYFUNC_BUFFERNORMAL
{
    public uint TopPoint;
    public uint EndPoint;
    public ushort Count;
    public IntPtr pGetData;
}
指向结构的指针是方法中的参数。C#功能是:

[DllImport("MYFUNC_DLL.dll", EntryPoint = "MYFUNC_GetData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall, ThrowOnUnmappableChar = true)]
public static extern int MYFUNC_GetData(IntPtr myfuncHandle, UInt32 dwIO, ref IntPtr pBufferNormal, Byte bccFlg);
这是C中的方法:

MYFUNC_STATUS MYFUNC_GetData(MYFUNC_HANDLE myfuncHandle, DWORD dwOut, MYFUNC_BUFFERNORMAL *pBufferNormal , BYTE bccFlg)
返回类型被强制转换为具有解释的枚举。结构参数无效。我尝试使用
封送.AllocHGlobal(…)
分配内存,但参数仍然无效,即编译期间没有错误,但返回的值不正确


我在这上面花了好几个小时,仍然不知道该怎么办。很多类似的问题已经存在了,比如这里:或者这里:,但不知何故,我仍然没有找到一种方法。

类似的方法应该有效,至少在数组中有一个元素(它是数组吗?)。对于数组,必须分配元素的
sizeof*count
,并在其偏移处封送(StructureToPtr)每个元素

var num = new MYFUNC_NUMERIC11();
num.Integer = new byte[] { 1, 2, 3 };
num.Decimal = new byte[] { 4, 5, 6, 7, 8, 9 };
num.Sign = 10;
num.Period = 11;

var buffer = new MYFUNC_BUFFERNORMAL();
buffer.Count = 1234;
buffer.EndPoint = 5678;
buffer.TopPoint = 9;
buffer.pGetData = Marshal.AllocCoTaskMem(Marshal.SizeOf(num));
try
{
    Marshal.StructureToPtr(num, buffer.pGetData, false);
    MYFUNC_GetData(Whatever, 0, ref buffer, 0);
}
finally
{
    Marshal.FreeCoTaskMem(buffer.pGetData);
}
根据这些定义

[StructLayout(LayoutKind.Sequential)]
public struct MYFUNC_BUFFERNORMAL
{
    public uint TopPoint;
    public uint EndPoint;
    public ushort Count;
    public IntPtr pGetData;
}

[StructLayout(LayoutKind.Sequential)]
public struct MYFUNC_NUMERIC11
{
    public byte Sign;
    
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public byte[] Integer;
    
    public byte Period;
    
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] Decimal;
}

// check calling convention
[DllImport(@"MYFUNC_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern MYFUNC_STATUS  MYFUNC_GetData(IntPtr myfuncHandle, uint dwIO, ref MYFUNC_BUFFERNORMAL pBufferNormal, byte bccFlg);

这不是“COM互操作”,而是p-invoke您使用windows约定而不是c语言调用:CallingConvention=CallingConvention.Cdecl
ref IntPtr pBufferNormal
不正确,请删除ref。或者更好的是,将其设为ref MYFUNC\u BUFFERNORMAL,这样您就不用自己封送所有内容了。dwCount成员强烈建议您可以使用MYFUNC_NUMERIC11[]pGetData。@DavidHeffernan是的,我正在尝试使用它。我想补充一句,没有成功。我实际上有一个元素数组,所以
sizeof*count
是我的选择。我尝试了一个元素,到目前为止看起来不错。仅供参考:我的呼叫约定是
StdCall
。我正在使用的DLL不支持您建议的约定。