Данные C ++ / WinRT Неправильная сортировка данных

Впервые в C ++ / WinRT и возникли некоторые проблемы с маршалингом данных при попытке экспортировать один класс C ++ с помощью C ++ / WinRT для использования в приложении .Net.

Я создал компонент среды выполнения Windows C ++ (Windows Universal) в Visual Studio 2017 v15.7.4.

Это сигнатура функции C ++, которую я пытаюсь использовать, поскольку она существует в файле заголовка, который я скопировал в проект C ++ / WinRT.

public:
short Carryout(unsigned char* p, unsigned short* pCh1, unsigned short* pCh2, unsigned short* pCh3, unsigned char* pCePa, unsigned short* pTAc);

Если это важный контекст fot, функция принимает массив байтов p в качестве входных данных и выводит 5 массивов, производных от него: pCh1, pCh2, pCh3, pCePa, pTAc.

Теперь в приложении .Net я объявил новый экземпляр класса из WinRT и настроил все буферы в качестве примера:

byte[] dataBlock = GetDataBlock();
ushort[] ch1s = new ushort[4096];
ushort[] ch2s = new ushort[4096];
ushort[] ch3s = new ushort[4096];
byte[] cepa = new byte[4096];
ushort[] tac = new ushort[1024];

WinRTClass wrtClass = new WinRTClass();
short x = wrtClass.Carryout(dataBlock, out ch1s, out ch2s, out ch3s, out cepa, out tac);

VS сообщает мне, что это неверно, потому что подпись не совпадает. Проверка определения функции переноса вызывает (что я предполагаю) автоматически сгенерированный файл заголовка (в его описании есть "из метаданных"), и подпись функции переноса в нем совершенно другая:

public short Carryout(out byte p, out ushort pCh1, out ushort pCh2, out ushort pCh3, out byte pCePa, out ushort pTAc);

Обратите внимание, что аргументы функции не являются массивами, а являются типами byte / ushort. Кроме того, первый аргумент не должен быть типом out. Как правильно устранить это несоответствие с помощью этого автоматически сгенерированного заголовка?

Я бы предпочел не вносить никаких изменений в код C ++: он имеет внутри довольно сложные манипуляции с данными и легко обеспечивает десятилетия выполнения, гарантируя, что все работает правильно.

Заранее спасибо!


person concentriq    schedule 19.06.2018    source источник
comment
В общедоступном интерфейсе могут быть только типы среды выполнения Windows. Указатели C ++ не являются типами среды выполнения Windows. Возможно, вам понадобится IVector ‹T› (или аналогичный). Непонятно, как вы публикуете свой тип в .NET. Вы используете файл IDL?   -  person IInspectable    schedule 19.06.2018
comment
@Inspectable спасибо: это, конечно, имеет смысл. Я предполагаю, что один из способов обойти это - добавить в C ++ новую функцию, которая использует типы WinRT. Я не использую файл IDL: я следовал основным инструкциям: скопировал некоторый код C ++ в новый проект WinRT, чтобы посмотреть, что произойдет. Учитывая, что компонент WinRT используется в одном приложении, следует ли мне его использовать?   -  person concentriq    schedule 20.06.2018
comment
Я не знаю, как создать файл .winmd без использования файла IDL. Для компонентов среды выполнения Windows вам понадобятся как компонент (DLL), так и метаданные (.winmd), чтобы использовать типы из любого поддерживаемого языка. В MSDN есть много полезной информации. Возможно, вы захотите прочитать Автор API с C ++ / WinRT, а также Использовать API с C ++ / WinRT.   -  person IInspectable    schedule 20.06.2018


Ответы (1)


Указатель в C / C ++ аналогичен ссылке в C # (слово «out», которое разрешает модификации). Объедините его с массивами, и вы получите:

public short Carryout(out byte[] dataBlock, out ushort[] ch1s, out ushort[] ch2s, out ushort[] ch3s, out byte[] cepa, out ushort[] tac);
person Ripi2    schedule 19.06.2018
comment
правильно: это то, что я ожидал, будет в автоматически сгенерированном файле заголовка, но это не так. Не похоже, что я могу вносить изменения из файла метаданных? - person concentriq; 19.06.2018
comment
Автоматическая генерация заголовка может запутаться, потому что в C ++ указатель является адресом чего-либо. Это может быть переменная, массив или что-то еще. - person Ripi2; 19.06.2018
comment
Это полностью упускает из виду суть. В общедоступном интерфейсе не может быть никаких типов, не относящихся к среде выполнения Windows. Принуждение ваших подписей к чему-то, чего они не делают, дает только одно: это нарушает ABI. - person IInspectable; 19.06.2018
comment
@ Ripi2 Да, я понимаю: как мне это исправить? Версия C # файла заголовка (автоматически сгенерированная) сохраняется не вместе с проектом, а в папке ../AppData/ ... Изменение этого автоматически сгенерированного файла заголовка не сохраняется, поэтому как мне убедиться, что версия C # сигнатуры функции остается правильной. Спасибо! - person concentriq; 19.06.2018