[英]Marshalling in c# ( Passing structure to an unmanaged type )
I have a c++ dll which exposes the following function 我有一个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];
}
I want to call this function from a C# application , so I do the following : 我想从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);
The application builds successfully. 应用程序构建成功。 When the C# application .exe is run, the function func()
is called successfully and it is able to populate the fields successfully inside the dll. 运行C#application .exe时,函数func()
被成功调用,并且能够在dll中成功填充字段。 But when the function returns to the C# application, the variable myname
still conatins null values for the struct fields( firstname
and lastname
). 但是当函数返回到C#应用程序时,变量myname
仍然会为结构字段( firstname
和lastname
)包含空值。
Please suggest changes so that I am able to populate the fields values of myname
(so that after the function func()
finishes execution, the variable myname->firstname
contains "rakesh" and myname->lastname
contains "agarwal". 请建议更改,以便我能够填充myname
的字段值(以便在函数func()
完成执行后,变量myname->firstname
包含“rakesh”, myname->lastname
包含“agarwal”。
Note: StringBuilder cannot be used inside the structure. 注意:StringBuilder不能在结构内部使用。
Instead of using an array, pass the struct by reference. 而不是使用数组,通过引用传递结构。 For a PInvoke call, a ref struct will be translated into a pointer to the struct. 对于PInvoke调用,ref struct将被转换为指向struct的指针。 The ref argument also tells the CLR to marshal data in both directions, to native code and then back out again. ref参数还告诉CLR在两个方向上编组数据,到本机代码然后再次退出。
[DllImport("C++Dll.dll")]
public unsafe static extern long func(ref name myname);
Also, if you're doing a lot of interop work I suggest you check out the PInvoke interop assistant ( link ). 此外,如果您正在进行大量的互操作,我建议您查看PInvoke互操作助手( 链接 )。 This tool will automatically convert the majority of C type definitions (including structs, enums, unions and function pointers) into their corresponding C# or VB.Net types. 该工具将自动将大多数C类型定义(包括结构,枚举,联合和函数指针)转换为相应的C#或VB.Net类型。 It will additionally convert signatures which contain these types. 它还将转换包含这些类型的签名。
Declare the import as public unsafe static extern long func(ref name myname)
, and call it as: 将导入声明为public unsafe static extern long func(ref name myname)
,并将其public unsafe static extern long func(ref name myname)
为:
name myname = new name();
func(ref myname);
You probably don't need the unsafe declarations on the name structure or import declaration, by the way. 顺便说一句,您可能不需要对名称结构或导入声明进行不安全的声明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.