【发布时间】:2017-01-06 19:01:35
【问题描述】:
我在 C 库中有一个结构:
#pragma pack(push, packing)
#pragma pack(1)
typedef struct
{
unsigned int ipAddress;
unsigned char aMacAddress[6];
unsigned int nodeId;
} tStructToMarshall;
__declspec(dllexport) int SetCommunicationParameters(tStructToMarshall parameters);
此代码使用cl /LD /Zi Communication.c 编译以生成用于调试的 DLL 和 PDB 文件。
为了在 .Net 应用程序中使用此代码,我使用 P/Invoke Interop Assistant 为包装 DLL 生成 C# 代码:
这会导致显示的 C# 包装器,我对其进行了修改以使用正确的 DLL 而不是 "<unkown>"。另外,我确实想要aMacAddress 的字节数组,而不是字符串(尽管我知道这通常会有帮助):
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct tStructToMarshall
{
/// unsigned int
public uint ipAddress;
/// unsigned char[6]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 6)]
public byte[] aMacAddress;
// ^^^^^^ Was "string"
/// unsigned int
public uint nodeId;
}
public partial class NativeMethods
{
internal const string DllName = "lib/Communication.dll";
/// Return Type: int
///parameters: tStructToMarshall->Anonymous_75c92899_b50d_4bea_a217_a69989a8d651
[System.Runtime.InteropServices.DllImportAttribute(DllName, EntryPoint = "SetCommunicationParameters")]
// ^^^^^^^ Was "<unknown>"
public static extern int SetCommunicationParameters(tStructToMarshall parameters);
}
我有两个问题: 1. 当我将结构的值设置为非零值并查找节点 ID 时,它被损坏或损坏。 IP 地址和 MAC 地址很好,但是数组后的任何结构成员(包括其他数据类型)都被破坏了,即使我指定了个位数的值,在 C 输出中也会显示非常大的数字。 2.当我调用该方法时,我收到一条错误消息:
对 PInvoke 函数 '' 的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
尝试调用不带参数的方法不会生成此异常。而且我很确定它与目标签名匹配,因为这就是我生成它的方式!
如何解决这些问题?
【问题讨论】:
标签: c# c pinvoke calling-convention packing