Unity与c++ 结构体中带数组参数传递

1 篇文章 0 订阅

在unity与c++ 进行交互中往往会有结构体的数据传递,如果在结构体中定义了数组,那么在unity中需要怎样去定义结构体从而对应c++中定义的带有数组的结构体呢.

请看代码:

#ifndef TRACK_H_H_
#define TRACK_H_H_

#define TRACK_POINT_SIZE 68
#define TRACK_MOUNT_POINT_SIZE 11

#ifdef __cplusplus
extern "C" {
#endif
typedef struct TrackPointCoord{
	float x;
	float y;
}TrackPointCoord;

typedef struct TRACK2DRET{
	TrackPointCoord allTrackPoints[TRACK_POINT_SIZE];
	TrackPointCoord mountTrackPoints[TRACK_MOUNT_POINT_SIZE];
    float  scale;
    float  angle;
    float  rendering_paramsy;
    float  rendering_paramsx;
}TRACK2DRET;

bool Track2DForUnity3D(unsigned char* rgba, TRACK2DRET* track2dRet);

#ifdef __cplusplus
}
#endif

#endif
在c++代码中定义了一个结构体,结构体中还定义了两个数组对象。那么c#该怎样定义呢

请看代码:

using System.Runtime.InteropServices;
using UnityEngine;
public struct TrackPointCoord
{
    public float x;
    public float y;
    public TrackPointCoord(float _x, float _y)
    {
        this.x = _x;
        this.y = _y;
    }
};

public struct TRACK2DRET
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 68)]
    public TrackPointCoord[] allTrackPoints;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
    public TrackPointCoord[] mountTrackPoints;
    public float scale;
    public float angle;
    public float rendering_paramsy;
    public float rendering_paramsx;

    public TRACK2DRET(TrackPointCoord[] _allTrackPoints, TrackPointCoord[] _mountTrackPoints, float _scale, float _angle, float _rendering_paramsy, float _rendering_paramsx)
    {
        this.allTrackPoints = _allTrackPoints;
        this.mountTrackPoints = _mountTrackPoints;
        this.scale = _scale;
        this.angle = _angle;
        this.rendering_paramsy = _rendering_paramsy;
        this.rendering_paramsx = _rendering_paramsx;
    }
};

public class TrackTool: Manager
{
  #region Android
#if UNITY_ANDROID
    [DllImport("TrackToolForUnity3D")]
    private static extern bool Track2DForUnity3D(byte[] rgba, ref TRACK2DRET track2dRet);
#endif
    #endregion

    /// <summary>
    /// 初始化结构体
    /// </summary>
    public TRACK2DRET InitStruct()
    {
        TrackPointCoord[] _allTrackPoints, _mountTrackPoints;
        TrackPointCoord _TrackPointCoord = new TrackPointCoord(0, 0);
        _allTrackPoints = new TrackPointCoord[68];
        _mountTrackPoints = new TrackPointCoord[11];
        for (int i = 0; i < _allTrackPoints.Length; i++)
        {
            _allTrackPoints[i] = _TrackPointCoord;
        }
        for (int i = 0; i < _mountTrackPoints.Length; i++)
        {
            _mountTrackPoints[i] = _TrackPointCoord;
        }
        TRACK2DRET track2dret = new TRACK2DRET(_allTrackPoints, _mountTrackPoints, 0, 0, 0, 0);
        return track2dret;
    }

//调用so
    public bool GetTarck2d(Color32[] Pixels,ref TRACK2DRET track2dret)
    {
        return Track2DForUnity3D(Color32ArrayToByteArray(Pixels), ref track2dret);
    }

	/// <summary>
    /// color32 array to byte array
    /// </summary>
    /// <param name="colors"></param>
    /// <returns></returns>
     byte[] Color32ArrayToByteArray(Color32[] colors)
    {
        if (colors == null || colors.Length == 0)
            return null;
        int length = Marshal.SizeOf(typeof(Color32)) * colors.Length;
        byte[] bytes = new byte[length];
        GCHandle handle = default(GCHandle);
        try
        {
            handle = GCHandle.Alloc(colors, GCHandleType.Pinned);
            Marshal.Copy(handle.AddrOfPinnedObject(), bytes, 0, length);
        }
        finally
        {
            if (handle != default(GCHandle))
                handle.Free();
        }
        return bytes;
    }
}
在c# 可以看到

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 68)]
MarshalAs属性指示如何在托管代码和非托管代码之间封送数据

[MarshalAs(UnmanagedType unmanagedType, 命名参数)]

实际上相当于构造一个MarshalAsAttribute类的对象

常用的UnmanagedType枚举值:

BStr   长度前缀为双字节的 Unicode 字符串;

LPStr  单字节、空终止的 ANSI 字符串。;

LPWStr  一个 2 字节、空终止的 Unicode 字符串;

ByValArray 用于在结构中出现的内联定长字符数组,应始终使用MarshalAsAttribute的SizeConst字段来指示数组的大小。

SizeConst值对应着c++中定义的结构体中数组大小.。

-----------------------》

在c#中想要获取c++中返回的结构体值需要使用ref方法。

[DllImport("TrackToolForUnity3D")]
    private static extern bool Track2DForUnity3D(byte[] rgba, ref TRACK2DRET track2dRet);
c++中:

bool Track2DForUnity3D(unsigned char* rgba, TRACK2DRET* track2dRet);
-----------------------------》

说下unsigned char* rgba参数

在c# 中需要定义对象为byte[]形式进行传值。上面代码中提供一个简便的将Color32[]转为byte[]方法。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值