Link to home
Start Free TrialLog in
Avatar of PingPhotonics
PingPhotonicsFlag for United Kingdom of Great Britain and Northern Ireland

asked on

C#.NET. How Do I get values of an array of longs in a C++ DLL?

Hello

Im developing a C#.NET application using Visual Studio 2008.

Im having trouble accessing data in a C++ DLL within my solution.

The C++ DLL is called myDLL.dll.  Ive defined this in my C#.NET code thus;

[DllImport(@"myDLL.dll")]
static extern int GetArray(UInt32[] pBuffer, int Size);

In the C++ source the code is like;

int GetArray(unsigned long* pBuffer, long BufferSz)
{
     int result = 0;
     //  
    // getValues in a manufacturer DLL. It returns a pointer to "unsigned long*"
    pBuffer = GetValues();

     return(result);
}

In my C++ DLL the GetArray function is exported thus;

__declspec(dllexport) int GetArray(unsigned long* pBuffer, long BufferSz);



I now try and access the values from my C#.NET code. ie.

int size = 1000;
UInt32[] pBuf = new UInt32[size];
int = GetArray(pBuf, size);

However I get an exception when I call GetArray. It is
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt"

Can anyone spot why this may not be working? Note we can't put a breakpoint in this particular DLL for some reason. We've spent ages trying to fix this but it seems its a known bug in Visual Studio.
Avatar of kaufmed
kaufmed
Flag of United States of America image

Have you tried marking pBuffer as a "ref" param and passing as such?

[DllImport(@"myDLL.dll")]
static extern int GetArray(ref UInt32[] pBuffer, int Size);

Open in new window

int size = 1000;
UInt32[] pBuf = new UInt32[size];
int = GetArray(ref pBuf, size);

Open in new window

may be use out instead of ref since c++ alloc memory
Avatar of PingPhotonics

ASKER

Hi thanks for the suggestion.
I tried it and when executing the GetArray function the debugger shows pBuf as containing uint[0].
ie. an array with one element set to zero.

Thats not what Im expecting. Im hoping to see  an array of 1000 elements.

SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@EDDYKT
may be use out instead of ref since c++ alloc memory
That shouldn't matter. The difference between "out" and "ref" is that when "ref" is used, the variable would be required to be initialized prior to passing into the function, which according to the above, it is. I concede that you could remove the initialization and then use "out" instead to save a small bit of processing (i.e. the managed initialization of the variable prior to the call).
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
kaufmed
I suspect you may be correct. Im investigating.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I thought I pointed to 'memcpy()' earler, didn't I?
Yup, but I hadn't noticed any non-C# responses as I scanned the question earlier, to be honest I just missed your comment.

At any rate, no one had yet to mention the calling convention issue, plus my comment slightly elaborated on yours (or at least attempts to do so) - so not quite a duplicate.
Curses!    I was going to mention calling convention, but I thought that's what "__declspec" was doing...   too much managed code for me, I guess  ; )
Hi
Thanks for the responses.

I tried changing the C# DLLImport definition to

 [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)] private static extern int GetArray(uint[] pBuff, int cBuff)

This didn't affect the result. Im now trying to get information from the vendors to tell me what the GetValues() function is doing. I'll report back when I hear from them.
Hi
Okay I managed to fix this. Due to poor documentation I had failed to set a parameter which caused the camera capture to fail and therefore the pointer didn't point to anything.
 Im not sure how to award points in this case so Im just going to award points to several of the answers which were generally useful and were relevant to the code I posted.