c# - 将结构数组从 C# 传递到 C++

标签 c# c++ marshalling

我需要将一个结构数组从 C++ 传递到 C#。我有以下代码,它首先创建一个临时结构,然后将其 memcpy 到 C# 端的结构地址。我用相同的元素顺序定义了两侧的结构。

当我调试时,我看到临时结构已正确填充,temp_buf(目标变量的地址)在每次迭代时结构的大小都会递增,并且 memcpy 不会返回任何错误。

但是,在 C# 端仅设置了数组的第一项。

以下是 C# 端的定义:

[DllImport(@"MyAwesomeDLL.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?GetDevices@@YAHPAXIPAIPAUDEVICE_S@@@Z", CharSet = CharSet.Auto)]
public static extern Int32 GetCoolDevices(out UInt32 p_deviceCount, out Device_s p_devicesBuf);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct Device_s
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
    public String DeviceName;
    public UInt32 DeviceID;
}

以下是 C++ 端的定义:

#pragma pack (1)
typedef struct
{
    TCHAR device_name [51];
    UINT32 device_rid;
} DEVICE_S;


int GetDevices (UINT32 *device_count, DEVICE_S *devices_buf)
{
....

    while(....)
    {
        DEVICE_S tmp_device;
        memset(&tmp_device, 0, sizeof(DEVICE_S));

        tmp_device.device_id = 5;
        sprintf( tmp_device.device_name, "a string");

        DEVICE_S *temp_buf = &(devices_buf[i]);
        size_t mysize =  sizeof(DEVICE_S);
        memcpy(temp_buf, &tmp_device, mysize);

        i++;
        getNextDevice();
    }

.....
}

而且,我是这样调用它的:

UInt32 MyDecDeviceCnt = 0;
Device_s[] MyDecDevices = new Device_s[10];
int ret = GetCoolDevices(out MyDecDeviceCnt, out MyDecDevices[0]);

如有任何建议,我们将不胜感激!

最佳答案

您创建的 API 有问题。您在托管端为数组分配内存(10 个元素),但不将数组中的元素数量传递到非托管端。编码器无法确定您想要编码 10 个元素,并且非托管代码不知道它正在写入的缓冲区的大小。

您可以使用MarshalAsAttribute.SizeParamIndex向编码器提供有关数组大小的信息。另请参阅文章Default Marshaling for Arrays 。 (特别是有关 C 样式数组的信息。)

考虑到 API 的性质,您可以更改它,以便在非托管端分配内存。您必须使用安全数组或 hglobal 来允许在托管端释放内存。

关于c# - 将结构数组从 C# 传递到 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10386610/

相关文章:

c# - 我可以在不丢失信息的情况下将 UInt32、Int32 和浮点值存储在 double 中吗?

c++ - 直接从已安装的 Windows 光栅(位图)字体获取位图

json.Marshal 对两个对象的行为不同 (Go/Golang)

json - 如何避免解析 ISuperObject 类型字段中的 json 对象

c# - 从 IEnumerable<T> 获取类型 T

c# - StreamReader 问题

c# - 防止回发 vb 和 javascript

c++ - 在qt c++中获取Json数组中Qstring的输出

c++ - 电源故障后 Windows 操作系统中的文件损坏

.net - .Net 中的 Marshal.DestroyStructure 与 Marshal.FreeHGlobal