Buongiorno,
spero qualcono possa aiutarmi.
On line ho trovato il codice di seguito riportato: sto riscrivendo un' applicazione che mi permetta di definire delle variabili il cui valore possa poi essere condiviso con altre applicazioni.
#include "stdafx.h"
#include "SharedMemorySrv.h"
#include "tchar.h"
#include "stdio.h"
extern HANDLE m_hFileMMF, m_pViewMMFFile, hMutex;
class CMutex
{
public:
CMutex()
{
if(!hMutex){
hMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
L"Global\\MMFMutex"); // unnamed mutex
}
WaitForSingleObject( hMutex, INFINITE);
}
~CMutex()
{
ReleaseMutex(hMutex);
}
};
void SetRecordCount(int value)
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
swprintf_s(record, MAX_PATH, L"RECCNT=%d#", value);
}
extern "C" int GetRecordCount()
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
int recordCount = -1;
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s ( temp, seps, &next_token1);
if(token1 && _tcscmp(token1, _T("RECCNT")) == 0)
{
token1 = _tcstok_s ( NULL, seps, &next_token1);
recordCount = _ttoi(token1);
}else
{
recordCount = 1;
SetRecordCount(1);
}
return recordCount;
}
int nRecordCount = -1;
extern "C" void RemoveValue(TCHAR* key)
{
CMutex mutex;
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
nRecordCount = GetRecordCount();
record+=MAX_PATH;
//Try to look. If found, break out of for loop
//Compact the memory immediately immediately
//If you get time, strongly advice you to do a lazy compaction
bool isRecordFound = false;
int i;
for(i= 1; i< nRecordCount; i++,record+=MAX_PATH)
{
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s (temp, seps, &next_token1);
if(_tcscmp(token1, key) == 0)
{
isRecordFound = true;
break;
}
}
//start moving the records
for(; i< nRecordCount-1; i++, record+=MAX_PATH)
{
TCHAR* nextRecord = record + MAX_PATH;
_tcscpy_s(record, MAX_PATH, nextRecord);
}
}
TCHAR* IfExists(TCHAR* key, TCHAR** value = NULL)
{
TCHAR* record = (TCHAR*)m_pViewMMFFile;
TCHAR temp[MAX_PATH];
nRecordCount = GetRecordCount();
record+=MAX_PATH;
for(int i=1; i< nRecordCount; i++,record+=MAX_PATH)
{
TCHAR seps[] = L"=#";
TCHAR *token1 = NULL;
TCHAR *next_token1 = NULL;
_tcscpy_s(temp, MAX_PATH, record);
token1 = _tcstok_s ( temp, seps, &next_token1);
if(_tcscmp(token1, key) == 0)
{
token1 = _tcstok_s ( NULL, seps, &next_token1);
//return a copy of the value
if(value!=NULL)
{
int len = _tcslen(token1)+1;
*value = new TCHAR(len);
_tcscpy_s(*value, len, token1);
}
return record;
}
}
return NULL;
}
extern "C" TCHAR* GetValue(TCHAR* key)
{
TCHAR* sRetVal = new TCHAR[MAX_PATH];
CMutex mutex;
TCHAR* data = NULL;
if(m_pViewMMFFile)
{
IfExists(key, &data);
}
return data;
}
extern "C" void SetValue(TCHAR* key, TCHAR* value)
{
CMutex mutex;
if(m_pViewMMFFile )
{
if(value == NULL)
{
RemoveValue(key);
}
else
{
TCHAR* data = IfExists(key);
if(data == NULL)
{
data = new TCHAR[MAX_PATH];
swprintf_s(data, MAX_PATH, L"%s=%s#", key, value);
//Add to end of the MMF
TCHAR* record = (TCHAR*)m_pViewMMFFile;
record += MAX_PATH*nRecordCount;
nRecordCount++;
SetRecordCount(nRecordCount);
_tcscpy_s(record, MAX_PATH, data);
delete data;
}
else
{
//Replace existing
swprintf_s(data, MAX_PATH, L"%s=%s#", key, value);
}
}
}
}
Il client che gestisce la scrittura e lettura è in C#: di seguito il codice che permette tutto ciò.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SharedMemoryClient
{
public partial class Form1 : Form
{
[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int GetRecordCount();
[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void SetValue(
[MarshalAs(UnmanagedType.LPTStr)] string key,
[MarshalAs(UnmanagedType.LPTStr)] string value);
[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]
extern static IntPtr GetValue([MarshalAs(UnmanagedType.LPTStr)]string key);
[DllImport("Test.dll", CallingConvention = CallingConvention.Cdecl)]
extern static IntPtr RemoveValue([MarshalAs(UnmanagedType.LPTStr)]string key);
public Form1()
{
InitializeComponent();
}
private void SetVar_Btn_Click(object sender, EventArgs e)
{
//Set
SetValue(VarName_TxtBox.Text, VarValue_TxtBox.Text);
UpdateRecordCount(null, null);
}
private void GetVar_Btn_Click(object sender, EventArgs e)
{
//Get
//StringBuilder sb = new StringBuilder();
IntPtr intPtr = GetValue(VarName_TxtBox.Text);
VarValue_TxtBox.Text = Marshal.PtrToStringUni(intPtr);
UpdateRecordCount(null, null);
}
private void UpdateRecordCount(object sender, EventArgs e)
{
linkLabel1.Text = "Count = " + GetRecordCount().ToString();
}
private void Remove_Btn_Click(object sender, EventArgs e)
{
RemoveValue(VarName_TxtBox.Text);
MessageBox.Show(VarName_TxtBox.Text.ToString() + ": removed !");
UpdateRecordCount(null, null);
}
}
}
Problema:
Definite per esempio 3 variabili in memoria chiamo la funzione "void RemoveValue(TCHAR* key)" per rimuoverne eventualmente una. La cosa strana che non riesco a capire è come mai riesco a cancellare tutte le variabili definite, tranne l' ultima: rimane sempre in memoria e riesco a leggere l' ultimo valore che gli impongo.
Qualcuno riesce a darmi una mano?
Grazie.
GreenBtn