Problem
I have a C # script that calls C functions through System.Runtime.Interop. I managed to call the C functions, but I have a buffer management problem between C and C #.
In my situation, C is a producer of data (data), and C # is a consumer.
My problem is that when I read data in C #, sometimes I get the correct value, but sometimes I get NULL.
This problem has already been resolved. I am inserting my wrong approach and my correct approach is here to share with you.
Background
C # code is a script unit (part of Mono development), and C code is in Xcode, which means I cannot use the .Net framework in my C code.
Wrong approach (gives me NULL from time to time)
Here is my C code (write to the buffer and read from the buffer):
static char InteropBF[INTEROP_BUFFER_SIZE];
static int mutex = 0;
void PutToBuffer(char* name, char* content)
{
while (mutex>0);
mutex++;
strcat(InteropBF, name);
strcat(InteropBF, ",");
strcat(InteropBF, content);
strcat(InteropBF, ",");
printf("Interop Buffer: %s\n", InteropBF);
mutex--;
}
void* ReadFromBuffer(void* temp)
{
while (mutex>0);
mutex++;
strcpy(temp, InteropBF);
strcpy(InteropBF, "");
mutex--;
return temp;
}
ReadFromBuffer() #:
[DllImport ("CCNxPlugin")]
public static extern IntPtr ReadFromBuffer(IntPtr temp);
:
IntPtr temp = Marshal.AllocCoTaskMem(8912);
CCN.ReadFromBuffer(temp);
string news = Marshal.PtrToStringAuto(temp);
if(news != "")
{
print (news);
}
Marshal.FreeCoTaskMem(temp);
, , NULL Marshal.PtrToStringAuto.
( !)
, -
C:
struct bufnode
{
char* name;
char* content;
struct bufnode *next;
};
struct bufnode* bufhead = NULL;
struct bufnode* buftail = NULL;
void PutToBuffer(char* name, char* content)
{
struct bufnode *temp = malloc(sizeof(struct bufnode));
temp->name = malloc(256);
temp->content = malloc(256);
strcpy(temp->name,name);
strcpy(temp->content,content);
temp->next = NULL;
if (bufhead == NULL && buftail == NULL) {
bufhead = temp;
buftail = temp;
}
else if(bufhead != NULL && buftail != NULL){
buftail->next = temp;
buftail = temp;
}
else {
printf("Put to buffer error.\n");
}
}
struct bufnode* ReadFromBuffer()
{
if (bufhead != NULL && buftail != NULL) {
struct bufnode* temp = bufhead;
if (bufhead == buftail) {
bufhead = NULL;
buftail = NULL;
}
else {
bufhead = bufhead->next;
}
return temp;
}
else if(bufhead == NULL && buftail == NULL)
{
return NULL;
}
else {
return NULL;
}
}
#:
[StructLayout (LayoutKind.Sequential)]
public struct bufnode
{
public string name;
public string content;
public IntPtr next;
}
[DllImport ("CCNxPlugin")]
public static extern IntPtr ReadFromBuffer();
#:
CCN.bufnode BufNode;
BufNode.name = "";
BufNode.content = "";
BufNode.next = IntPtr.Zero;
IntPtr temp = CCN.ReadFromBuffer();
if(temp != IntPtr.Zero)
{
BufNode = (CCN.bufnode)Marshal.PtrToStructure(temp, typeof(CCN.bufnode));
print(BufNode.name);
print(BufNode.content);
Marshal.FreeCoTaskMem(temp);
}