1

I'm using WINAPI dll written in C++ using DllImport for accessing USB ADC/DAC converter values. The only problem is:

long ZGetBufferADC(long typeDevice, long numberDSP, void **buffer, long *size)

I've translated it into

[DllImport("Zadc.dll")]
public static extern Int32 ZGetBufferADC(Int32 typeDevice, Int32 numberDSP, out IntPtr    buffer, out Int32 size);

I call this function like that

Int32 err = ZGetBufferADC(typeDevice, numberDSP, out pBuffer, out sizeBufferADC);

Then I need to access resulting pBuffer in C# like that in C++:

short *pBuffer16ADC = (short*) pBuffer
volt0 = resolutionADC0 * (pBuffer16ADC[pointerADC]) / amplifyADC0;

where pointerADC is Int32 pointing to current value of ADC converter, i managed to get it w/o problems correctly

so how could i implement that structure in c#? I tried defining variables like that

IntPtr pBuffer;
Int16 pBuffer16ADC; 
pBuffer16ADC = (Int16)pBuffer;
volt0 = resolutionADC0 * (pBuffer16ADC[pointerADC]) / amplifyADC0;

but that throws an error

Cannot apply indexing with [] to an expression of type 'short'

Any help will be appreciated! If additional info is needed please ask i'll provide ASAP. This issue is driving me nuts for almost a week :( Thanks!

5
  • 1
    Having IntPtr buffer filled by ZGetBufferADC, use IntPtr p = Marshal.ReadIntPtr(buffer); Then pBuffer16ADC = Marshal.ReadInt16(p); Commented Oct 11, 2013 at 5:14
  • Assuming that C++ code is short *pBuffer16ADC = (short*) *pBuffer; Your C++ code fragment doesn't match function definition. Commented Oct 11, 2013 at 5:15
  • That's something! If I apply your code then same error about indexing appears. However, when I omitted the index program compiled well but on Marshall.ReadInt16(p) throws System.AccessViolationException was unhandled (cannot write memory) . Locals show that p variable is negative number (-2359241). Commented Oct 11, 2013 at 6:43
  • For the second comment: code short *pBuffer16ADC = (short*) pBuffer (w/o asterisk before pBuffer) that it's how it's written in c++ assuming pBuffer is defined like void *pBuffer; Can I upload code somewhere? It's not large, and easy-to-read. Maybe I am missing something. Commented Oct 11, 2013 at 6:43
  • 1
    I don't know how @Alex reached that conclusion. You presumably pass &pBuffer16ADC to the function. And that is a double pointer. Commented Oct 11, 2013 at 8:07

1 Answer 1

1

Presumably size is measured in bytes. If instead, size is the number of elements, it should be obvious how to adapt the following.

First of all, call the function as you are doing:

Int32 err = ZGetBufferADC(typeDevice, numberDSP, out pBuffer, out sizeBufferADC);

Then declare an array into which you copy the buffer.

short[] buffer = new short[sizeBufferADC/Marshal.SizeOf(typeof(short))];

Finally copy the buffer:

Marshal.Copy(pBuffer, buffer, 0, buffer.Length);

And that should be all you need to do.

Sign up to request clarification or add additional context in comments.

4 Comments

Can't thank you enough, it's working flawlessly :) However, it worth noting that in C# it's short[] buffer, this could confuse someone somehow) But the idea is awesome, so simple and stable.
Thanks. Glad it helped. Too much C++ lately, hence the syntax slip. Now fixed. Perhaps I should have used var!!
There is a problem with Marshal.Copy....it's awful perfomance-wise, because my buffer is constantly changing and copying it in every timer tick is costly. I thought if I could get away with Marshal.ReadIntPtr instead, but i can't figure out what offset is needed. I tried Marshal.ReadIntPtr(pBuffer,pointerADC*sizeof(short)), pBuffer is IntPtr, pointerADC is the index of 16-bit array, like that: pBuffer16ADC[pointerADC] where short[] pBuffer16ADC = new short[sizeBufferADC]; size in 16-bit words.
There's not a whole lot you can do about that given the interface of the function. I'd expect that a C++/CLI mixed mode wrapper would perform better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.