Hi all
I am Vivek Bhola, working C#.net. I am trying to invoke a unmanaged code function in c#code. This function has prototype like:
public static extern int SsmRecToFileA(int ch, string pszFileName, int nFormat, int dwStartPos, int dwBytes, int dwTime, int nMask, LPRECTOMEM pfnCallbackA);

here pfnCallbackA is pointer to a callback function and it.s prototype and deffinition is:

public delegate void LPRECTOMEM(int ch, ref byte lpData, uint dwDataLen);
 CardAPI.LPRECTOMEM pfnLiveListening = new CardAPI.LPRECTOMEM(LiveListening);

private static void LiveListening(int ch, ref byte lpData, uint dwDataLen)
        {
            try
            {
               
                byte[] VoiceBuffer =  new byte[dwDataLen];

                IntPtr ptrData = new IntPtr(lpData);
               
                [B]Marshal.Copy(ptrData, VoiceBuffer, 0, Convert.ToInt32(dwDataLen));[/B]

                 if (CardAPI.SsmPlayMem(ch, 6, VoiceBuffer, dwDataLen, 0, dwDataLen) == -1)
                {
                    MessageBox.Show(CardAPI.SsmGetLastErrMsgA());
                   
                }
               
            }
            catch (Exception exp)
            { 
            
            }
                       
        }

when I call SsmRecToFileA function, after every 2 seconds callback function gets Called.
In this callback function i need to access the buffer pointed by lpData. So I copy the entire content on this address to a local buffer called voicebuffer through Marshal.copy method.
ACTUAL PROBLEM BEGINS NOW, at Bold line i.e Marshal.copy . It gives me an exception:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
and stack trace is :

at System.Runtime.InteropServices.Marshal.CopyToManaged(IntPtr source, Object destination, Int32 startIndex, Int32 length)
at System.Runtime.InteropServices.Marshal.Copy(IntPtr source, Byte[] destination, Int32 startIndex, Int32 length)
at ATP_Event.Form1.LiveListening(Int32 ch, Byte& lpData, UInt32 dwDataLen) in D:\My Projects\Synway-Digital\Copy of Synway Digital VL1.0.1\ATP_Event\Form1.cs:line 1214

Please tell where I am wrong? Please reply soon.

Recommended Answers

All 12 Replies

What are the values of:

ptrData, VoiceBuffer, lpdata and dwdatalen before you hit the marshall line?

What are the values of:

ptrData, VoiceBuffer, lpdata and dwdatalen before you hit the marshall line?

The Values of above variables are:
ptrData = new IntPtr(lpData);
dwdatalen = 16384
VoiceBuffer = new byte[dwDataLen]

lpdata = address of Buffer of raw data.

Thanks for reply.

Thats not really what I asked the only answer you gave me was dwdatalen ..

What were the values..

Thats not really what I asked the only answer you gave me was dwdatalen ..

What were the values..

ok you want the raw values. These are:
ptrData = 131;
dwdatalen = 16384
VoiceBuffer ={0,0,0,0,0,0,0,0,... upto 16384 elsements}

lpdata = 131.

I think above are the values what you want.

131 seems an unlikely answer for the pointer however, lets assume it is.

if lpdata = prtdata whats the point of making a second pointer? Why not use the one you have.. Perhaps this is part of the issue.

Marshal.Copy(lpdata, VoiceBuffer, 0, Convert.ToInt32(dwDataLen));

however, still 131 strikes me as a bad pointer.

131 seems an unlikely answer for the pointer however, lets assume it is.

if lpdata = prtdata whats the point of making a second pointer? Why not use the one you have.. Perhaps this is part of the issue.

Marshal.Copy(lpdata, VoiceBuffer, 0, Convert.ToInt32(dwDataLen));

however, still 131 strikes me as a bad pointer.

Actually , the buffer I am trying to point resides in one device's driver memory area. And lpdata is of byte reference type and marshal.copy has no constructor which takes a source as byte rerfernce. Therefore , I needed to convert it into IntPtr.
and as far as as value of lpData is concerned which is 131 , it is coming when a call of livelistening is made by the ssmRecToFileA third party function.

It still seems mighty odd that 131 would be a valid point in memory, thats extreemly low, even for a device driver.

The other thing that seems to stand out is your lpdata should be an array surely? its a single byte..

I have ran into this before, when trying to communicate between drivers and applications.

If you are running on Vista with sp1 this is a no no, and it will give you this error.

I would recommend changing your code to either use registry or file to communicate between the app and driver to eliminate your protected memory issue.

I have ran into this before, when trying to communicate between drivers and applications.

If you are running on Vista with sp1 this is a no no, and it will give you this error.

I would recommend changing your code to either use registry or file to communicate between the app and driver to eliminate your protected memory issue.

Thanks for your reply

Can you tell me , how could I do whatever you have told me. Please explain.

Well that depends, what type of driver are you communicating with?

Also how much data are you trying to send it? Like a variable or two, or like pages worth of information?

And also how frequently?

You could probably bundle it in another bit of unmanaged code to take the data and write it to file using c/c++/delphi etc, and have it send a message to your app to indicate picking up of a file..

Hi,

I had a similar problem trying to call a C dll from my C# app. Whenever a callback function was called I got the protected memory error even if my function did nothing with the value passed.

A couple of friends helped me out to resolve the problem which in our case meant putting __stdcall in front of any callbacks in the declaration in the C dll, e.g. our original declaration was say,

__declspec(dllexport) int myfunc(char logtype,void(*cb_func)(char *))
{
...
}

where cb_func is the callback.

We changed it to,

__declspec(dllexport) int myfunc(char logtype,void(__stdcall *cb_func)(char *))
{
...
}

Apparently the C++ compilers default to cdecl instead of stdcall for callbacks but in C# they have to be stdcall. Using the wrong type means that the wrong end is thinking it is responsible for cleaning up the stack (e.g. caller instead of callee or vice versa) and hence the protected memory error.

It's probably obvious I don't completely know what I am talking about but I hope this helps someone.

TamW

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.