我正在编写一个C++ dll来对从VBA传递过来的SAFEARRAY进行排序。将索引数组排序到主数组
我没有使用任何OLE库,而是直接访问数组描述符和数据。
我对排序任何本机VBA类型的数组没有任何问题。例如,下面的代码片段排序BSTRs数组:
long * p = (long*)pData;
std::sort(p, p + elems, comparestring);
...使用这种比较函数:
bool comparestring(const long& lhs, const long& rhs) {
wchar_t * lhs_ = (wchar_t*)lhs;
wchar_t * rhs_ = (wchar_t*)rhs;
return _wcsicmp(lhs_, rhs_) < 0;
}
我知道我欺骗在这里,因为wchar_t
是BSTR
很大的不同,但在Excel字符串的有效内容中有一个零字符并不常见,所以我对此很满意。以上运作良好。
技术问题
我想的dll任选能够索引的同伴数组进行排序到初级数据数组。在这种模式下,只有索引数组将被排序,而不会改变源数据。
我的研究表明lamda仿函数可能是最有希望的路径,因为我宁愿不为其他数组或向量的数据或配对分配内存。
特别是,this answer seems very promising。
但是,我不能解决如何适应我的情况,我正在处理从pData开始的BSTR的原始指针。
我曾尝试以下:
long * p = (long*)pData;
long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i + 1;
std::sort(ndx[0], ndx[4], [&p](long i1, long i2) { comparestring((*p) + i1, (*p) + i2); })
我使用VC++ 2015和下面的错误上面的结果:
Error C2893 Failed to specialize function template 'iterator_traits<_Iter>::iterator_category std::_Iter_cat(const _Iter &)'
我的C语言编程的日子古代历史(早于存在的C + +),所以我挣扎了一下。感谢任何帮助。
UPDATE
代码现在看起来是这样..它编译,但执行后的ndx
顺序不正确:
long * p = (long*)pData;
long ndx[5];
for (int i = 0; i < 5; i++) ndx[i] = i + 1;
std::sort(ndx, ndx + 5, [&p](long i1, long i2) { return comparestring(*p + i1, *p + i2); })
拉姆达需要返回一个布尔值(例如'返回comparestring .....' –
你也可能是指'NDX,NDX + 5'而不是' ndx [0],ndx [4]'。这应该使它编译,但在我看来,你的指针抛出骇客仍然生产垃圾 –
谢谢。我尝试使用将'比较字符串'里面的三个语句直接放入lambda,并且尽管它会返回一个布尔值,但我得到了完全相同的错误 –