0

New to C++/WinRT and haivng some trouble marshalling data when trying to export a single C++ class using C++/WinRT for use in a .Net application.

I created a C++ Windows Runtime Component (Windows Universal) in Visual Studio 2017 v15.7.4.

This is the signature of the C++ function I am trying to use as it exists in the header file I copied into C++/WinRT project

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

If its important fot context, the function takes a array of bytes p as input and spits out 5 arrays derived from it: pCh1, pCh2, pCh3, pCePa, pTAc.

Now in .Net application I declared new instance of the class from WinRT and setup all of the buffers just as an example:

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 tells me this isnt correct because signature doesnt match. Checking Definition of Carryout function brings up (what I assume to be) an automatically generated header file (has "from metadata" in its description) and the signature of the Carryout function in it is quite different:

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

Note that function arguments are not arrays, but rather a byte/ushort types. Also, first argument is is not supposed to be an out type. What is the proper way to address this discrepancy with this automatically generated header?

I would rather not make any changes to the C++ code: it has rather complex data manipulation inside, and easily decades of runtime assuring that it all works correctly.

Thank you in advance!

concentriq
  • 359
  • 2
  • 6
  • 16
  • 1
    You can only have Windows Runtime types in your public interface. C++ pointers aren't Windows Runtime types. You'll probably want an [IVector](https://learn.microsoft.com/en-us/uwp/api/windows.foundation.collections.ivector_t_) (or similar). It's unclear, how you are exposing your type to .NET, too. Are you using an IDL file? – IInspectable Jun 19 '18 at 19:37
  • @IInspectable thank you: this makes total sense, of course. Im guessing one way to go around it would be to add new function to C++ that uses WinRT types. I am not using IDL file: i was following basic instructions: copied some C++ code into new WinRT project just to see what would happen. Considering that WinRT component is used within same application, Is it something I should be using? – concentriq Jun 19 '18 at 22:27
  • I'm not aware of a way to generate a .winmd file without use of an IDL file. For Windows Runtime components you need both the component (DLL) as well as the metadata (.winmd) to consume the types from any supported language. There's lots of useful information in the MSDN. You'll probably want to read [Author APIs with C++/WinRT](https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-apis) as well as [Consume APIs with C++/WinRT](https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/consume-apis). – IInspectable Jun 19 '18 at 22:56

1 Answers1

-1

A pointer in C/C++ is similar to a reference in C# (word 'out' which allows modifications). Combine it with arrays and it gives you:

public short Carryout(out byte[] dataBlock, out ushort[] ch1s, out ushort[] ch2s, out ushort[] ch3s, out byte[] cepa, out ushort[] tac);
Ripi2
  • 7,031
  • 1
  • 17
  • 33
  • right: this is what I expected would be in the automatically generated header file, but it isnt. It doesnt appear that I can modify "from metadata" file? – concentriq Jun 19 '18 at 19:27
  • Automatic header generation can get confused because in C++ a pointer is the address of "something". This "something" may be a variable, or an array or whatever. – Ripi2 Jun 19 '18 at 19:31
  • 1
    That's completely missing the point. You cannot have any non-Windows Runtime type in your public interface. Forcing your signatures to something they aren't only does one thing: It breaks the ABI. – IInspectable Jun 19 '18 at 19:39
  • @Ripi2 Yes, I understand that: how do i correct this? The C# version of the header file (auto generated) is not stored with the project, but rather in ../AppData/.. folder. Modifying this autogenerated header file does not persist, so how do i make sure that C# version of the function signature stays correct. Thank you! – concentriq Jun 19 '18 at 19:40