【发布时间】:2021-05-06 10:13:38
【问题描述】:
我想在 c# 中使用 c++ dll。我正在使用[DllImport] 来调用该方法。我在将结构传递给方法时遇到问题。
我有一个 C 结构体:
typedef struct
{
DWORD TopPoint;
DWORD EndPoint;
WORD dwCount;
MYFUNC_NUMERIC11 *pGetData;
} MYFUNC_BUFFERNORMAL;
MYFUNC_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# 结构来模仿这一点。
[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)
返回类型被强制转换为具有解释的枚举。结构参数无效。我尝试使用Marshal.AllocHGlobal(...)分配内存,但参数仍然无效,即编译时没有错误但返回的值不正确。
我已经为此花费了好几个小时,仍然无法弄清楚该怎么做。已经存在很多类似的问题,比如这里:How do I convert c struct from dll to C# 或这里:How to pass C# array to C++ and return it back to C# with additional items?,但不知何故,我仍然没有找到办法。
【问题讨论】:
-
这不是 "COM-interop" 而是 p-invoke
-
您正在使用 windows 约定而不是 c 语言进行调用:CallingConvention = CallingConvention.Cdecl
-
ref IntPtr pBufferNormal不正确,删除 ref。或者更好的是,将其设为 ref MYFUNC_BUFFERNORMAL,这样您就不必自己编组所有内容。 dwCount 成员强烈建议您可以使用 MYFUNC_NUMERIC11[] pGetData。 -
@DavidHeffernan 是的,我正在尝试使用它。不成功,我可以补充一下。