Я кодирую dll C++ для сортировки SAFEARRAY, переданного из VBA.Сортировка массива индексов в первичный массив
Я не использую никаких библиотек 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, и поэтому я в порядке с этим. Это хорошо работает.
ПРОБЛЕМА
Я хочу, чтобы дллы необязательно иметь возможность сортировать компаньон массив индексов в массив первичных данных. В этом режиме будет отсортирован только массив индексов, оставив исходные данные нетронутыми.
Мои исследования показывают, что функтор lamda может быть наиболее перспективным путем, поскольку я бы предпочел не выделять память для дополнительных массивов или векторов данных или пар.
В частности, this answer seems very promising.
Однако я не могу решить, как адаптировать его к моей ситуации, когда я обрабатываю необработанные указатели на BSTR, которые начинаются с pData.
Я попытался следующие:
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] '.Это должно заставить его скомпилировать, но мне кажется, что ваш hackery-указатель-манипулятор по-прежнему создает нежелательный файл. –
Спасибо. Я попытался использовать три выражения из' 'compestestring'' непосредственно в лямбда, и хотя бы он возвращал логическое значение, я получил ту же ошибку. –