我必须找到在C ++ Win32端构建结构数组的方法。我没有最初的项目数。调整该数组的速度应该非常快。
构建列表时,我需要将其返回给.NET。因此,数组(列表)应该转换为可以在.NET端轻松读取的传输,或者初始列表可以“按原样”使用,只需传递指针。
先谢谢你给我一个提示!
答案 0 :(得分:3)
通常,如果使用CLI支持编译C ++ dll,则只需使用托管容器即可。如果您不希望使用CLI选项编译您的dll,那么您可以编写小型C ++ / CLI包装器DLL,它将从本机C ++ DLL调用方法并在托管容器中存储对象。 另一种可能的解决方案是更改C ++ lib的接口以通过索引返回对象,支持插入和/或删除。
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
函数。
答案 1 :(得分:3)
实现&#34;动态数组的一种非常常见的方式&#34;在C ++中使用STL的 std::vector
。在您的情况下,您可以定义vector<SomeData>
。 std::vector
可以根据您的请求动态更改动态(即在运行时):您可以将push_back
或emplace_back
方法用于此目的,向矢量添加新项目。
然而,C#并没有理解&#34; std::vector
。
要将其内容整理到C#,您可以使用 SAFEARRAY
,这是CLR非常了解的。 SAFEARRAY的好处在于它除了数组内容之外还存储了数组大小:它是一个独立的数据结构。
因此,您可以创建一个适当大小的SAFEARRAY,用向量中动态创建的内容填充它,并将该SAFEARRAY传递给C#。
请注意,您也可以直接构建SAFEARRAY,而不传递std :: vector。但STL的矢量具有更强大的编程接口;所以如果你想在运行时通过push_back或emplace_back做几个项目的添加,首先构建std :: vector,然后&#34; marshalling&#34;进入SAFEARRAY,可能是更好的选择。无论如何,这取决于您的特定需求和背景。
作为替代方案,您可以使用C ++ / CLI作为C ++端和C#端之间的桥接层。在这种情况下,您可以使用gcnew
来创建.NET&#34;托管&#34;的 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;
}