在c#中编组(将结构传递给非托管类型)

3 c# pinvoke

我有一个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];
}
Run Code Online (Sandbox Code Playgroud)

我想从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);
Run Code Online (Sandbox Code Playgroud)

应用程序构建成功.运行C#application .exe时,该函数func()被成功调用,并且能够在dll中成功填充字段.但是当函数返回到C#应用程序时,变量myname仍然会为结构字段(firstnamelastname)保留空值.

请建议更改,以便我能够填充字段值myname(以便在函数func()完成执行后,变量myname->firstname包含"rakesh"并myname->lastname包含"agarwal".

注意:StringBuilder不能在结构内部使用.

Jar*_*Par 7

而不是使用数组,通过引用传递结构.对于PInvoke调用,ref struct将被转换为指向struct的指针.ref参数还告诉CLR在两个方向上编组数据,到本机代码然后再次退出.

[DllImport("C++Dll.dll")]
public unsafe static extern long func(ref name myname);
Run Code Online (Sandbox Code Playgroud)

此外,如果您正在进行大量的互操作,我建议您查看PInvoke互操作助手(链接).该工具将自动将大多数C类型定义(包括结构,枚举,联合和函数指针)转换为相应的C#或VB.Net类型.它还将转换包含这些类型的签名.