【发布时间】:2012-02-09 11:51:23
【问题描述】:
我在 C++ 中有一个方法,它有两个参数:byte 和 ushort,它返回指向非常困难的结构的指针(它是 C++ 项目中几乎所有结构的联合)。
当我在 C# 中使用 DllImport 调用此方法时,例如传递它 1 和 2,它使用一些随机字节数和 1 调用(因此第一个参数作为第二个参数传递,而真正的第一个参数取自一些不同的内存地址)。
我能想到的唯一一种解释是返回结构没有正确映射,因此所有参数都有偏移。但我不知道如何检查它。是否有任何工具可以向我显示由 C# 生成的编组数据的地址和大小,以便我可以使用我在 C++ 中收到的地址来检查它们?或者您可以建议的任何其他解决方案。
--- 更新---
在注释了 C++ 和 C# 的代码结构后,我将测试代码简化为: C++:
enum PrimitiveType: unsigned short
enum ErrorType : unsigned char
typedef struct
{
PrimitiveType Primitive;
unsigned char InstNo; /* The instance number. */
ErrorType ErrorCode; /* ERR_NO_ERROR */
unsigned char Active; /* True = relay active */
} GetRelayCfmType;
sizeof(GetRelayCfmType) = 5
C#:
enum PrimitiveType : ushort
enum ErrorType : byte
[StructLayout(LayoutKind.Sequential)]
public struct GetRelayCfmType
{
public PrimitiveType Primitive;
public byte InstNo; /* The instance number. */
public ErrorType ErrorCode; /* RTX2300_ERR_NO_ERROR */
public byte Active; /* True = relay active */
};
Marshal.Sizeof(new GetRelayCfmType()) == 6.
为什么一个字节的大小不同? 更新。
现在我的函数是(C++):
__declspec(dllexport) GetRelayCfmType __stdcall GetRelay_Blocking(unsigned char InstNo, RelayNoType No)
enum RelayNoType : unsigned char
所以在 C# 中我有:
[DllImport(DLL_NAME, CallingConvention = CallingConvention.StdCall)]
public static extern GetRelayCfmType GetRelay_Blocking(byte InstNo, RelayNoType No);
enum RelayNoType : byte
现在图片已满。
【问题讨论】:
-
第 1 步:显示足够的代码供我们帮助。
-
你用clrinterop.codeplex.com/releases/view/14120检查DLLimport代码是否正确?
-
这就像 100 多个结构。正如我所说,这个函数非常简单——它接受字节和 ushort,返回值是混蛋。它是由这 100 多个结构组成的联合体。此外,由于保密协议,我无法上传它,也无法翻译,因为我不知道问题出在哪里。这就是为什么我要求您不要指出问题出在哪里,而是通过一些示例帮助我解决此类问题。
-
你确定你导入了正确的方法吗?在我最近使用的一个 dll 中,我正在使用的头文件中声明了 2 个版本的方法,一个用于 Mac,一个用于 Windows,其签名略有不同。我导入了错误的参数,并且由于参数不符合 dll 的预期顺序,它的行为不正确。
-
你确定你用对了calling convention?
标签: c# c++ debugging pinvoke dllimport