【发布时间】:2013-04-26 02:09:35
【问题描述】:
假设我在 C 中有以下结构
typedef struct
{
int field1;
char field2[16];
} MYSTRUCT;
现在我有一个用指向 MYSTRUCT 的指针调用的 C 例程,我需要填充结构,例如,
int MyCall(MYSTRUCT *ms)
{
char *hello = "hello world";
int hlen = strlen(hello);
ms->field1 = hlen;
strcpy_s(ms->field2,16,hello);
return(hlen);
}
如何用 C# 编写 MyCall?我在 Visual Studio 2010 中试过这个:
...
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
public struct MYSTRUCT
{
[FieldOffset(0)]
UInt32 field1;
[FieldOffset(4)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
string field2;
}
public int MyProc(ref MYSTRUCT ms)
{
string hello = "hello world";
int hlen = hello.Length;
Marshal.Copy(hello, ms.field2, 0, hlen); // doesn't work
Array.Copy(hello, ms.field2, hlen); // doesn't work
// tried a number of other ways with no luck
// ms.field2 is not a resolved reference
return(hlen);
}
感谢有关正确方法的任何提示。
【问题讨论】:
-
ms.field2=hello;,但您可能正在寻找其他东西。显示调用MyProc的代码可能有用... -
我还注意到您在 C 中的结构是 int 类型而不是 unsigned int,因此在 C# 中您可能希望将数据类型设为 Int32 而不是 UInt32
-
其次,如果您将程序移植到 C#,则不必使用结构布局,如果您要通过引用传递结构,您不妨将其设为类,因为它通过引用传递。然后,您可以根据需要分配您的值。现在,如果您的函数被导出到动态库,那么您可以使用结构化布局做得很好。
-
当您在 C# 中使用 Marshal 或 Array 副本时,您不需要做任何特别的事情。在您使用完结构并需要将其发送回非托管方法后,只需将其传递给 p/invoked 调用,内置的编组将完成所有工作。与从 p/invoked 方法返回结构相同 - 如果您正确定义结构,.NET 将为您完成编组工作。
-
除非我在这里完全脱离了球并且你根本没有在本机代码之间编组......我假设你正在用你所有的编组东西做......在这种情况下,只是像使用 C# 中的任何其他类一样使用它:)
标签: c# windows visual-studio-2010