调整包装类以适应二维情况

2023-12-01

这个问题是这个问题的延伸question.

我想调整包装器以适应二维情况。这是我的第一次尝试:

public class EmxArrayRealTWrapper : IDisposable
{
private readonly emxArray_real_T _value;
private GCHandle _dataHandle;
private GCHandle _sizeHandle;

public emxArray_real_T Value
{
    get { return _value; }
}

public EmxArrayRealTWrapper(double[,] data)
{
    _dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
    _value.data = _dataHandle.AddrOfPinnedObject();
    _sizeHandle = GCHandle.Alloc(new int[] { data.GetLength(0), data.GetLength(1) }, GCHandleType.Pinned);
    _value.size = _sizeHandle.AddrOfPinnedObject();
    _value.allocatedSize = data.GetLength(0) * data.GetLength(1) * sizeof(double);
    _value.numDimensions = 2;
    _value.canFreeData = false;
}

public void Dispose()
{
    _dataHandle.Free();
    _sizeHandle.Free();
    GC.SuppressFinalize(this);
}

~EmxArrayRealTWrapper()
{
    Dispose();
}
}

[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
{
public IntPtr data;
public IntPtr size;
public int allocatedSize;
public int numDimensions;
[MarshalAs(UnmanagedType.U1)]
public bool canFreeData;
}

PS:

原始的 matlab 代码如下所示:

    function [x] = test(a)
    %#codegen

    x = 0;
    if(~isempty(coder.target))
      assert(isa(a,'double'));
      assert(all(size(a) == [1 Inf]));
   end

    x = sum(a);

并且可以像这样调用:

a = [ 1 2; 3 4]

r = test(a)

生产:

r =

     4     6

不幸的是,生成的 C 无法实现 Matlab 可以实现的功能(即返回一个数组):

__declspec(dllexport) real_T test(const emxArray_real_T *a);

real_T test(const emxArray_real_T *a)
{
  real_T x;
  int32_T k;
  if (a->size[1] == 0) {
    x = 0.0;
  } else {
    x = a->data[0];
    for (k = 2; k <= a->size[1]; k++) {
      x += a->data[k - 1];
    }
  }

  return x;
}

我假设 MATLAB 数组结构使用 col-major 排序。在这种情况下,结构体构造函数需要如下所示:

public EmxArrayRealTWrapper(double[,] data)
{
    int nRow = data.GetLength(0);
    int nCol = data.GetLength(1);

    double[] flattenedData = new double[nCol * nRow];
    int index = 0;
    for (int col=0; col<nCol; col++)
    {
        for (int row=0; row<nRow; row++)
        {
            flattenedData[index] = data[row, col];
            index++;
        }
    }                    

    _dataHandle = GCHandle.Alloc(flattenedData, GCHandleType.Pinned);
    _value.data = _dataHandle.AddrOfPinnedObject();
    _sizeHandle = GCHandle.Alloc(new int[] { nCol, nRow }, GCHandleType.Pinned);
    _value.size = _sizeHandle.AddrOfPinnedObject();
    _value.allocatedSize = nCol * nRow;
    _value.numDimensions = 2;
    _value.canFreeData = false;
}

如果本机代码需要行优先,那么它会更简单。 C# 多维数组存储为连续的行优先数组。因此,您可以使用与我在最近的问题中提供的一维代码非常相似的代码。

public EmxArrayRealTWrapper(double[,] data)
{
    int nRow = data.GetLength(0);
    int nCol = data.GetLength(1);
    _dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
    _value.data = _dataHandle.AddrOfPinnedObject();
    _sizeHandle = GCHandle.Alloc(new int[] { nRow, nCol }, GCHandleType.Pinned);
    _value.size = _sizeHandle.AddrOfPinnedObject();
    _value.allocatedSize = nCol * nRow;
    _value.numDimensions = 2;
    _value.canFreeData = false;
}

请注意,这两种变体将数据传递给本机代码的方式有所不同。第一个版本传递原始数据的副本。第二个传递对原始数据的引用。我不确定你希望你的代码如何表现。修改第二个版本来传递副本很容易。对于第一个版本,如果您希望本机代码修改数据并将这些修改反映回托管代码,那么您需要在本机调用返回后将修改封送回来。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调整包装类以适应二维情况 的相关文章

随机推荐

  • Python:如何使冒泡排序的实现更加省时?

    这是我的代码 用于按升序对列表元素进行排序的冒泡排序算法 foo 7 0 3 4 1 cnt 0 for i in foo for i in range len foo 1 if foo cnt gt foo cnt 1 temp foo
  • 如何在 Python 2.7 中用另一个类修饰实例方法?

    在Python 2 7中我想装饰一个实例方法test在班上Foo带有一个装饰器 它也是一个名为FooTestDecorator 来自用户 Chirstop 的question和 Python 2 文档 描述符操作指南我创建了这个例子 然而
  • 在 Android 中更改运行时语言

    我必须更改 Android 运行时的语言 是的 我知道这不是一个好的行为 但这是一个要求 所以我有一个基础课程 每项活动都从它延伸而来 该类具有以下功能 public static void changeLanguage Context c
  • Boost hana 获取第一个匹配的索引

    所以我正在尝试使用以下方法创建一个库boost hana这需要根据值获取元素索引的功能 constexpr auto tup boost hana make tuple 3 c boost hana type c
  • Silverlight 和 WCF:NotFound 错误!

    我有像这样的 WCF 方法 public string GetSomething MyObject obj return Something 当我从 silverlight 应用程序调用此函数时 出现错误 System Net WebExc
  • 如何按小时对数据进行分组?

    我已将数据读入 R 尝试使用以下代码按小时对数据进行分组 tweets lt read csv tweetCSV csv header TRUE sep stringsAsFactors FALSE tweets gt group by f
  • AJAX(原型/php)在脚本执行期间获取部分状态更新

    我有一个想要在页面后台运行的进程 该过程将需要一段时间才能运行 比如说几分钟 我已对其进行设置 以便从页面中单击按钮来启动该进程 稍等片刻 然后它就会完成 并且我可以让页面更新通知我该进程已成功运行 我正在使用原型和 php 来完成此操作
  • HQL 查询中 Hibernate 表未映射错误

    我有一个 Web 应用程序 它使用 Hibernate 对数据库进行 CRUD 操作 我收到一条错误消息 指出该表未映射 查看Java文件 错误信息 org springframework orm hibernate3 HibernateQ
  • 需要从 ansible json stdout 获取值并将它们放入列表中

    鉴于此输入 stdout lines apiVersion v1 items apiVersion v1 kind Namespace metadata annotations
  • C 中的数组列表不工作

    我目前正在编写一个程序来在 C 中实现数组列表 或动态数组 嗯 我想我已经完成了 70 80 但是 在对几个代码进行测试时 我发现我的代码存在严重问题机器 简而言之 我将一组字符串 char 插入到我的数组列表中 并尝试在几次操作后获取并显
  • 将数字四舍五入到最接近的 3 的倍数

    我该如何将数字四舍五入到最接近的 3 倍数 i e 25 would return 27 1 would return 3 0 would return 3 6 would return 6 if n gt 0 return Math ce
  • 如何在 Microsoft Workflow 中调用另一个 Activity 中的 Activity?

    我已经创建了一个本机活动 并且需要在书签恢复调用中调用另一个活动 我的第一个活动名称是 申请 第二个活动名称是 批准 在应用中 我创建了一个属性 如下所示 public Approve Approve get set 然后我注册了 Cach
  • Jenkins Powershell 输出

    我想捕获一些变量的输出 以便在工作中的其他地方使用Jenkins Powershell 插件 这可能吗 我的目标是以某种方式构建最新的标签 而 powershell 脚本就是为了实现这一点 输出到文本文件不会有帮助 并且无法使用环境变量 因
  • 尝试实施 AdMob 横幅时 ClassNotFound

    当尝试使用 admob sdk 4 3 1 在我的 Android 应用程序中实现 admob 横幅时 我遇到了一个非常烦人的 ClassNotFound 异常 我使用了以下实现 显现
  • 如何获取网页
    标签内的元素?

    我想访问网站 表单 标签内存在的按钮 如果我打印表单的内部文本 我可以获取整个页面 但我不知道如何访问表单内的元素 尝试过的代码 Dim workFrame As HTMLFormElement test As HTMLFormElemen
  • 如何分析 Oracle 存储过程的端到端性能

    我想知道从外部进程访问数据库并说执行此操作到数据库返回到进程并说开始 我的存储过程需要多长时间才能执行 有没有一种简单易行的方法来完成这项非常基本的任务 当然 关于存储过程执行期间发生的情况以及执行每个任务 插入 plsql 字符串操作等
  • 在backbone.js中从一个视图中访问另一个视图中的函数

    我有这样的视图结构 window templateLoaderView Backbone View extend window PopupView templateLoaderView extend initialize function
  • AndroidStudio升级到1.0后出现NoClassDefFoundError(12月8日)

    以前版本的 Android Studio 可以与候选版本 4 12 月 4 日 或更高版本正常工作 FATAL EXCEPTION main java lang NoClassDefFoundError com google android
  • 为 iPhone 4 SDK 构建的 Blocks 在部署到 iPhone OS 3.0 时可以工作吗?

    如果您将应用程序设置为部署到早期版本 则最新的 Xcode IDE 要求您以 iPhone SDK 4 为目标 同时动态处理已弃用的功能和新功能 那么 我可以使用 Blocks 等新功能 并且仍然可以在运行 iPhone OS 3 0 3
  • 调整包装类以适应二维情况

    这个问题是这个问题的延伸question 我想调整包装器以适应二维情况 这是我的第一次尝试 public class EmxArrayRealTWrapper IDisposable private readonly emxArray re