-1

I need to import a C-function which is descripted as

int Read(LPBYTE data, LPBYTE lengthOfData);

The documentation says the following:

data

[out] data which was read

lengthOfData

[out] length of data which was read

And there is the following example of using this function:

int num = 0;
BYTE data[16] = {0};
while (num < 6)
{
   int dataLen = 0;
   Read(data, &dataLen);
   num += dataLen;
}

How to import this function?
As I understand, the first one parameter is an array of bytes.

Can I import it as:

public static extern int Read([Out] IntPtr data, [Out] byte dataLength);

or I should use out keyword, maybe?

EngineerSpock
  • 2,575
  • 4
  • 35
  • 57
  • The snippet doesn't make any sense, &dataLen is incompatible with LPBYTE. Then again, using a BYTE to store a buffer length doesn't make any sense either. It is *probably* `int Read(byte[] data, ref int length)`. – Hans Passant May 06 '15 at 13:13
  • `ref` in C? `LPBYTE` can be marshaled as either C# `IntPtr` or C# `byte`. – EngineerSpock May 06 '15 at 13:30
  • No, a pointer to BYTE cannot be marshaled as `byte`. If my recommendation does not work then use a telephone. – Hans Passant May 06 '15 at 13:35
  • I'm confused. This article http://www.codeproject.com/Articles/9714/Win-API-C-to-NET says that "LPBYTE can be marshaled as IntPtr or byte". There is a matching table in the article. – EngineerSpock May 06 '15 at 13:44
  • It pretends there is no difference between BYTE and LPBYTE. That's nonsense of course, typical codeproject lossage. – Hans Passant May 06 '15 at 13:51
  • The array should be `[Out] byte[] data` but as Hans points out your C code is wrong. Please post the real C code. – David Heffernan May 06 '15 at 13:57
  • @DavidHeffernan unfortunately I have only a document. I don't have a real C-code. I posted theirs example AS IS. As I understand, it's likely that there is an error in the doc concerning the second argument, right? Maybe it should be of the BYTE type? And by the way, can I really use just `[Out] byte[] data` instead of `[Out] IntPtr data` dealing with allocation through Marshal? – EngineerSpock May 06 '15 at 14:03
  • Something does not match. – David Heffernan May 06 '15 at 14:07
  • This document is from China. I'm afraid it will be pretty hard to telephone them. – EngineerSpock May 06 '15 at 14:09

1 Answers1

0

If the function really is:

int Read(LPBYTE data, LPBYTE lengthOfData);

Then the correct translation would be:

[DllImport(..., CallingConvention = CallingConvention.Cdecl)]
static extern int Read([Out] byte[] data, out byte dataLength);

But that doesn't match your C code. The C code won't even compile mind you. Perhaps the second parameter is really an int.

To call this function you need to allocate the array before calling.

byte[] data = new byte[16];
byte dataLength;
int retval = Read(data, out dataLength);

You need to clear up the following details:

  • What is the type of that second parameter?
  • What is the calling convention?
  • How do you determine how to pre-allocate the array?

The function is poorly designed because it does not allow the caller to specify how long the array is and thus runs the risk of buffer overrun.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490