I'm importing in my C# program an unmanaged dll containing C functions. One of those functions needs a structure as an argument. This function gets a structure that has been sent on the network. The function was first designed to pass char*, so I used unsafe environment to pass my structure.
Everything my code first works except that I got two exceptions coming out everytime the GetMsg function has run for about 15 times. Those exceptions are :
'System.AccessViolationException' occurred in mscorlib.dll
'System.StackOverflowException' occurred in mscorlib.dllHere's what I've done :
I know it works, because I can get the data. The exceptions always sent me back at the second code snippet, so it must be something with the marshaling I use. I wanna know if what I've done is OK or if something is missing or if there are any other ways of doing this.
Here's what I've done so far :
[DllImport(PATH_TO_DLL, CharSet = CharSet.Ansi, PreserveSig = true)]
unsafe static extern int MDComAPI_getMsg(
[In, Out, MarshalAs(UnmanagedType.SysUInt)] IntPtr queue,
[In, Out, MarshalAs(UnmanagedType.Struct)] ref MSG_INFO pMsgInfo,
char** ppData,
[In, Out, MarshalAs(UnmanagedType.U4)] ref UInt32 pDataLength,
int timeOut);
Then I use the function I imported:
unsafe static public int GetMsg(IntPtr queue, ref MSG_INFO pMsgInfo, char* pData, ref UInt32 pDataLength, int timeOut)
{
int Ret = MDComAPI_getMsg(queue, ref pMsgInfo, &pData, ref pDataLength, timeOut);
return Ret;
}
This function is used to get messages on a network. Later on, I passed a structure and I want to get the structure and display different statuses. All of this is done on a backgroundworker
// information structure to be passed as an argument in the imported dll function
struct MSG_INFO
{
...
};
// Structure that has been sent on the network and that I need to get with the
// imported dll function
struct Status
{
...
};
MSG_INFO msgInfo = new MSG_INFO();
while (true)
{
char[] recbuf = new char[100];
fixed (char* pRecBuf = recbuf)
{
UInt32 bufLength = Convert.ToUInt32(recbuf.Length);
{
try
{
// Look until the message queue (recQueue) is empty
while(AppsIPTCom.GetMsg(recQueue, ref msgInfo, pRecBuf, ref bufLength, 0) == 1)
{
if (msgInfo.msgType == DATA)
{
if (bufLength == sizeof(Status))
{
// A message has been received...
Status* lStatus = (Status*)pRecBuf;
// CALL THE RICHTEXTBOXSTATUS FROM AN INVOKE FUNCTION
// etc.
}
}
}
}
catch (Exception e_)
{
MessageBox.Show(e_.Message, STR_ERROR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
Thread.Sleep(500);
}
If you have any clues, please help.
Thank you,
Jerome