我有一个公开以下函数的 C++ dll
long func(struct name * myname)
{
strcpy(myname->firstname,"rakesh");
strcpy(myname->lastname,"agarwal");
return S_OK;
}
struct name
{
char firstname[100];
char lastname[100];
}
我想从 C# 应用程序调用此函数,因此我执行以下操作:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
unsafe public struct name
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)]
public string firstname;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string lastname;
} ;
[DllImport("C++Dll.dll")]
public unsafe static extern long func(name[] myname);
name[] myname = new name[1];
func(myname);
应用程序构建成功。当 C# 应用程序 .exe 运行时,函数 func()
被成功调用,并且能够成功填充 dll 中的字段。但是当函数返回到 C# 应用程序时,变量 myname
仍然包含结构字段(firstname
和 lastname
)的空值。
请提出更改建议,以便我能够填充 myname
的字段值(以便在函数 func()
完成执行后,变量 myname ->firstname
包含“rakesh”,myname->lastname
包含“agarwal”。
注意:结构内部不能使用StringBuilder。
最佳答案
不使用数组,而是通过引用传递结构。对于 PInvoke 调用,ref 结构将被转换为指向该结构的指针。 ref 参数还告诉 CLR 在两个方向上将数据编码到 native 代码,然后再次退出。
[DllImport("C++Dll.dll")]
public unsafe static extern long func(ref name myname);
此外,如果您正在进行大量互操作工作,我建议您查看 PInvoke 互操作助手 (link)。该工具会自动将大部分 C 类型定义(包括结构、枚举、联合和函数指针)转换为它们对应的 C# 或 VB.Net 类型。它还会转换包含这些类型的签名。
关于c# - 在 c# 中编码(将结构传递给非托管类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/789977/