Click to See Complete Forum and Search --> : Shared memory w/ unmanaged DLL
Jeremy Johnson
April 15th, 2003, 01:33 PM
This is my first excursion into .NET development, so please forgive any novice oversights...
I'm trying to write a C# application that accesses shared memory in an unmanaged Win32 DLL.
The Win32 DLL defines the shared memory in such a fashion:
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// define shared memory
//
// data must be initialized! data_seg pragma applies only to initialized data.
#pragma data_seg(".SHAREDMEMORY")
int gshared_nTest = 0;
#pragma data_seg()
// sets linker switch for shared memory section
#pragma comment(linker, "/SECTION:.SHAREDMEMORY,RWS");
How can I get my C# application to access this shared memory? Is it even possible?
Thanks,
Jeremy
pareshgh
April 15th, 2003, 06:57 PM
actually for unmanaged stuff !!,
so what you should do is , if you want the shared memory information then you should create a function which returns the information or array,
and later on you can access that array in C# by following. C++ array creation is your side !!!
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
public struct Short2DArray
{
public const int ElementSize = 2;
[FieldOffset(0)]
private int _size0;
[FieldOffset(4)]
private int _size1;
[FieldOffset(8), MarshalAs(UnmanagedType.ByValArray)]
public readonly short[] shortArray;
[FieldOffset(8), MarshalAs(UnmanagedType.ByValArray)]
public readonly byte[] byteArray;
public Short2DArray(int size0, int size1)
{
_size0 = size0;
_size1 = size1;
shortArray = new short[size0 * size1];
byteArray = new byte[size0 * size1 * ElementSize];
}
public byte this[int index]
{
get { return byteArray[index]; }
set { byteArray[index] = value; }
}
public short this[int index0, int index1]
{
get
{
if (index0 >= _size0 || index1 >= _size1)
throw new ArgumentOutOfRangeException();
return shortArray[index0 * _size0 + index1];
}
set
{
if (index0 >= _size0 || index1 >= _size1)
throw new ArgumentOutOfRangeException();
shortArray[index0 * _size0 + index1] = value;
}
}
public int ShortSize
{
get { return _size0 * _size1; }
}
public int ShortSize0
{
get { return _size0; }
}
public int ShortSize1
{
get { return _size1; }
}
public int ByteSize
{
get { return ElementSize * _size0 * _size1; }
}
public byte[] GetSafeBytes()
{
byte[] ret = new byte[ByteSize];
Buffer.BlockCopy(byteArray, 0, ret, 0, ByteSize);
return ret;
}
public short[,] GetSafeShorts()
{
short[,] ret = new short[_size0, _size1];
Buffer.BlockCopy(byteArray, 0, ret, 0, ByteSize);
return ret;
}
}
Paresh
Jeremy Johnson
April 23rd, 2003, 02:09 PM
Thanks!!
I also received this helpful reply from MatiasN on www.gotdotnet.com:
[Begin quote from MatiasN]
Yes, you can. But you will need access to the underlying dll that contains the shared memory in order to create functions that can get/set the shared memory values ( or perform whatever action on the shared memory that you need to.
I thought this was an interesting example, so I quickly created something that should work. Its primitive, but it proves the point. The following code snippet is from a VC++ 7.0 project and this is the main cpp file.
( By the way the semi-colon you had on your original #pragma comment line was unnecessary and will cause a compiler warning ).
//=================================================
#include "stdafx.h"
#pragma data_seg(".SHAREDMEMORY")
int gshared_nTest=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.SHAREDMEMORY,RWS")
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) int __stdcall getMyData()
{
return gshared_nTest;
}
extern "C" __declspec(dllexport) void __stdcall setMyData( int data )
{
gshared_nTest = data;
}
//================== END OF CPP FILE ==================
Note: You must declare it as extern "C" in order to prevent the mangling of names. This is absolutely necessary in order to import it into a c# project.
//=================================================
To test this you can create a simple console application with the following code snippet. I put the message box in there so I could run multiple console applications at the same time and pause them so that I could see the shared memory values changing.
//=================================================
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestShared
{
class TestShared
{
[DllImport(@"C:\VS Projects\Shared\Debug\Shared.dll")]
public static extern int getMyData();
[DllImport(@"C:\VS Projects\Shared\Debug\Shared.dll")]
public static extern void setMyData(int data);
[STAThread]
static void Main(string[] args)
{
setMyData( getMyData() + 100 );
MessageBox.Show( getMyData().ToString() );
}
}
}
-MatiasN
[End quote from MatiasN]
pareshgh
April 23rd, 2003, 03:14 PM
good. yes I had seen that . its actually kind of tough problem when u deal with C++ specially with memory since it has to pass thru several layers to talk with memory.
Paresh
Jeremy Johnson
April 24th, 2003, 11:51 AM
I've successfully shared Integers, but I'm running into problems when I attempt to share a simple struct.
Here's what I'm defining in the unmanaged DLL:
--------------------------------------------------------------
typedef struct
{
int vt;
int nVal;
double dVal;
} BP_SHARED_DATA;
extern "C" __declspec(dllexport) BP_SHARED_DATA ReadPipe();
--------------------------------------------------------------
ReadPipe() is just returning my shared structure (not shown).
Here's the .NET side of things:
--------------------------------------------------------------
public class BrowserPipe
{
[StructLayout( LayoutKind.Sequential)]
public class SHARED_DATA
{
public Int32 vt;
public Int32 nVal;
public Double dVal;
};
[DllImport(@"BrowserPipe.ocx")]
public static extern SHARED_DATA ReadPipe();
}
---------------------------------------------------------------
Whenever I call ReadPipe(), I get a "System.NotSupportedException". I've also tried defining "SHARED_DATA" as a struct, but it doesn't solve the problem.
Any suggestions? Oh, I should mention that I'm using the Compact Framework.
Thanks!
Jeremy
pareshgh
April 24th, 2003, 12:34 PM
try using with another kind of Layout strucutre..
Paresh
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.