Rimuovere variabile condivisa tra 2 o piu applicazioni - C++ dll

domenica 07 agosto 2011 - 22.19
Tag Elenco Tags  C#  |  .NET 4.0  |  Visual Studio 2010

GreenButton Profilo | Newbie

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
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5