【问题标题】:PInvoke addressingPInvoke 寻址
【发布时间】: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


【解决方案1】:

在您请求我们的帮助之前,您显然需要更多信息。看看这篇文章:http://msdn.microsoft.com/en-us/library/eahchzkf(v=vs.100).aspx 注意所做的声明。

虽然可以使用 Marshal.SizeOf 方法,但返回的值是 此方法并不总是与 sizeof 返回的值相同。 Marshal.SizeOf 返回类型被编组后的大小, 而 sizeof 返回由公共分配的大小 语言运行时,包括任何填充。

我怀疑这是因为结构内的填充。您已允许 .NET 对结构进行顺序布局。这当然允许它猜测某些事情。我会使用 Explicit 设置 Pack 值,甚至可能是 Size 值。

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 1970-01-01
    • 2019-02-27
    • 2013-04-07
    • 2011-03-12
    • 2015-03-18
    • 2017-05-16
    • 1970-01-01
    • 2011-02-13
    相关资源
    最近更新 更多