gpt4 book ai didi

c# - 使用 P/Invoke 时存储非托管代码的数据

转载 作者:行者123 更新时间:2023-11-27 23:55:28 25 4
gpt4 key购买 nike

我有这个结构的数组数组(在 C# 中显示,但也存在于 C++ 中):

[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
IntPtr name; //pointer to string, char* on C++ side

long pValues;
long jValues;
long eValues;
long kValues;

int cost;
};

以及在 C++ DLL 中运行的算法,从托管 C# 代码调用。它占用大量 CPU,这正是它在 C++ 中运行速度比 C# 快得多的必要条件。托管 (C#) 端永远不必知道结构数据的内容,因为该算法仅返回一个整数数组。

那么,在应用程序的生命周期内,我将如何以最有效的方式(即开销最少)存储这些数据?我想我已将其缩小为两个选项:

  1. 在 C# 中初始化结构和设置值,使用 GCHandle 固定内存并在我想工作时传递对 C++ 的引用(参见 Unity 论坛上的 this post)

  2. 在 C++ 中初始化结构和设置值,使结构在非托管端持久存在内存中

所以我的问题非常具体:

对于 1,我对编码的工作方式感到困惑。它看起来像 MSDN: Copying and Pinning您可以通过固定和传递对固定数据的引用来传递结构数组,无需复制或转换任何数据(只要结构在两侧看起来相同) .我读得对吗,它实际上是这样工作的吗?引用 Unity3d 论坛帖子,我看到 Marshal.PtrToStructure 被调用;我认为执行复制操作?由于在这种情况下数据将存储在托管端,因此每次调用 C++ 函数时都必须复制和/或转换数据会导致大量开销,除非我认为这些类型的操作很多比实际价格更贵。

对于 2,我想知道是否可以在 C++ 调用之间保持持久性。据我所知,如果您是从 DLL 进行 P/调用,则无法在非托管端拥有持久数据,因此我不能只在那里定义和存储我的结构数组,从而使唯一的数据在两者之间传输managed 和 unmanaged 由非托管算法产生的 int 数组。这是正确的吗?

非常感谢您花时间阅读并提供帮助!

最佳答案

如果 C# 代码不需要了解数组和结构的内部结构,请不要将其暴露给 C# 代码。在非托管代码中完成此类型的所有工作并避免编码开销。

从本质上讲,您要遵循这个基本模式。我敢肯定细节会有所不同,但这应该为您提供基本概念。

C++

MyStruct* newArray(const int len)
{
return new MyStruct[len];
}

void workOnArray(MyStruct* array, const int len)
{
// do stuff with the array
}

void deleteArray(const MyStruct* array)
{
delete[] array;
}

C#

[DllImport(dllname)]
static extern IntPtr newArray(int len);

[DllImport(dllname)]
static extern void workOnArray(IntPtr array int len);

[DllImport(dllname)]
static extern void deleteArray(IntPtr array);

关于c# - 使用 P/Invoke 时存储非托管代码的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42921449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com