【问题标题】:Why is this String empty when invoking/marshaling this struct from C# to C-DLL?为什么从 C# 调用/编组这个结构到 C-DLL 时这个字符串是空的?
【发布时间】:2016-07-15 09:55:51
【问题描述】:

我在 C-DLL 中定义了这样的函数:

int AcquireArchive (char* archiveName, Password* password)

结构密码在DLL中定义为:

typedef struct password {
unsigned char* pPwd;
unsigned long length;
} Password;

我正在做的是尝试用 C# 包装这个函数:

[DllImport("name.dll", CharSet = CharSet.Ansi, EntryPoint = "_AcquireArchive@16", 
CallingConvention = CallingConvention.StdCall)]
public static extern int AcquireArchive(
[MarshalAs(UnmanagedType.LPStr)] string archiveName, 
ref Password password
);

和:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Password
{ 
    public string pwd;
    public ulong length;
}

我通过以下方式调用此函数:

Password password;
password.pwd = "password";
password.length = (ulong)password.pwd.Length;

int code = AcquireArchive("Archive", ref password);

现在的问题是返回的代码发出 INVALID PASSWORD 信号,指示(根据文档)密码长度为 0。 password.pwd 和/或 password.length 的值是否可能在调用/编组过程中丢失?

遗憾的是,我无法访问 dll 的源代码。

编辑:CharSet 现在是 Ansi,TYPO “长度”,已删除 [UnmanagedType.BStr]

【问题讨论】:

  • C++ 代码肯定使用 Unicode 吗?因为CharSet.Auto 会在 WINdows XP 或更高版本上假设。
  • 它不是 UnmanagedType.BStr,删除它。 struct 上的 CharSet.Auto 错误,必须使用 CharSet.Ansi。
  • 我认为这里有一个错误:password.lenght
  • @MatthewWatson:OP 询问的是 C,而不是 C++!
  • @Olaf 同样的问题也适用——不管它的 C 还是 C++ 对结构的编组方式没有任何影响。

标签: c# c dll interop marshalling


【解决方案1】:

我看到了至少一个问题:
在您的 C 代码中(长度为 32 位或 64 位,具体取决于 DLL):

typedef struct {
  unsigned char* pPwd;
  unsigned long length;
} Password;

在你的 C# 代码中(长度为 64 位):

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Password
{ 
    public string pwd;
    public ulong length;
}

如果是 64 位的,就可以了。 但如果它是 32 位的,则应将 C# ulong 更改为 uint,如下所示:

public struct Password
{
    public string pwd;
    public uint length;
}  

我希望这会有所帮助。

【讨论】:

  • 确实是这个问题!非常感谢!
  • 在使用 InteropServices 时,是否有任何类型的数据类型兼容性概览表?这样可以避免这样的错误
  • @sascha-g:对于这种类型的兼容性,恐怕不行。但要将托管类型转换为非托管类型,请参见:msdn.microsoft.com/en-us/library/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2015-11-09
  • 1970-01-01
  • 2010-10-15
  • 2014-09-01
  • 2011-12-06
相关资源
最近更新 更多