如何在c++中构建动态数组并将其返回到c# /. net
How to build a dynamic array in C++ and return it back to C#/.NET
我必须找到在c++ Win32端构建结构体数组的方法。我没有初始项数。调整数组的大小应该非常快。
当列表被构建时,我需要将它返回到。net。因此,数组(列表)应该转换为可以在。net端轻松读取的传输,或者初始列表可以"原样"使用,只是传递指针。
提前感谢你给我的提示!
在c++中实现"动态数组"的一种非常常见的方法是使用STL的 std::vector
。在您的示例中,您可以定义一个vector<SomeData>
。std::vector
可以动态地改变它的大小(即在运行时),根据您的要求:您可以使用它的push_back
或emplace_back
方法用于此目的,向矢量添加新项。
然而,c#并不"理解"std::vector
。
要将其内容封送到c#中,您可以使用 SAFEARRAY
, CLR对此非常理解。SAFEARRAY的好处是,除了数组内容之外,它还存储数组大小:它是一个自包含的数据结构。因此,你可以创建一个大小合适的SAFEARRAY,用vector中动态创建的内容填充它,并将该SAFEARRAY传递给c#。
注意,您也可以直接构建SAFEARRAY,而不传递std::vector。但是STL的vector有一个更强大的编程接口;因此,如果您希望在运行时通过push_back或emplace_back进行几项添加,则首先构建std::vector,然后将其"编组"到SAFEARRAY中,可能是更好的选择。无论如何,这取决于你的特殊需求和环境。
作为替代方案,您可以使用c++/CLI作为c++端和c#端之间的桥接层。在这种情况下,你可以使用gcnew
来创建一个。net "managed" array
。
并且,作为另一种选择,您可以使用C接口从本机c++ DLL中导出两个函数:
-
获取数组中项目计数的函数
-
另一个函数,用于在输出调用者分配的缓冲区中获取实际数组数据(其大小由前一个函数返回)
在c#中,输出缓冲区指针是通过IntPtr
输出参数传递的。然后可以使用Marshal.PtrToStructure
封送单个数据项,并且可以使用Marshal.SizeOf
增加指针,使其指向数组中的下一个项。
像这样:
// In C++:
struct SomeData
{
/* your data fields */
};
// Export these two functions from your native DLL:
extern "C" int GetSomeDataCount( /* some params */ );
extern "C" void GetSomeData( SomeData* ptr, /* some other params */ );
// In C#:
public struct SomeData
{
// Map C++ data structure fields to C#
}
static extern int GetSomeDataCount( /* some params */ );
static extern void GetSomeData( [Out] out IntPtr ptr, /* some other params */ );
SomeData[] GetSomeData( /* some params */ )
{
// Allocate an array of proper size
SomeData[] dataArray = new SomeData[ GetSomeDataCount( /* some params */ ) ];
// Fill the array with content from GetSomeData
IntPtr dataPtr;
GetSomeData( out dataPtr, /* some other params */ );
for (int i = 0; i < dataArray.Length; i++)
{
dataArray[i] = Marshal.PtrToStructure(dataPtr, typeof(SomeData));
dataPtr += Marshal.SizeOf(typeof(SomeData));
}
return dataArray;
}
一般来说,如果你的c++ dll是用CLI支持编译的,你可以简单地使用托管容器。如果你不想用CLI选项编译你的dll,那么你可以编写一个小的c++/CLI包装器dll,它将调用本地c++ dll中的方法,并将对象存储在托管容器中。另一个可能的解决方案是改变c++库的接口,使其按索引返回对象,支持插入和/或删除。
std::vector<CFoo> vec;
void init() {
//read data to vec
}
CFoo getIthElement(int i) {
return vec[i];
}
int getElementCount() {
return vec.size();
}
所以你将在c#端使用getIthElement
和getElementCount
函数
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- 如何使函数返回数组?用于制作在VB.NET中使用的DLL
- C++/CLI:返回对 C#.NET 应用中非托管对象的引用
- 从ASP.NET应用程序查询Active Directory对象属性将返回旧结果
- 如何在.NET Visual Basic应用程序中读取从C++DLL返回的const char*
- 通过.NET中的指针从本机方法返回数据
- . net调试API SetManagedHandler返回E_NOINTERFACE
- 使用c++ . net MySQL连接器的参数化查询不返回结果
- .net 4.0 -如何防止在64位Windows上从c++到c#返回字符串时出现AccessViolationExce