1

Sorry for probably simple question but I'm newbie in shared memory and trying to learn by example how to do things.

On c++ side I receive such pair: const unsigned char * value, size_t length On c# side I need to have regular c# string. Using shared memory what is the best way to do that?

Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305

1 Answers1

0

It's not that easy to using the string.

If it's me, I'll try these ways:

1.simply get a copy of the string. System.Text.Encoding.Default.GetString may convert from a byte array to a string.

You may try in a unsafe code block (for that you could use pointer type) to do:

(1) create a byte array, size is your "length"

byte[] buf = new byte[length];

(2) copy your data to the array

for(int i = 0; i < length; ++i) buf[i] = value[i];

(3) get the string

string what_you_want = System.Text.Encoding.Default.GetString(buf);

2.write a class, having a property "string what_you_want", and each time you access it, the above process will perform.

before all, you should first using P/Invoke feature to get the value of that pair.

edit: this is an example.

C++ code:

struct Pair {
    int length;
    unsigned char value[1024];
};

#include <windows.h>
#include <stdio.h>
int main()
{
    const char* s = "hahaha";
    HANDLE handle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(Pair), L"MySharedMemory");
    struct Pair* p = (struct Pair*) MapViewOfFile(handle, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(Pair));
    if (p != 0) {
        p->length = lstrlenA(s);
        lstrcpyA((char*)p->value, s);
        puts("plz start c# program");
        getchar();
    } else
        puts("create shared memory error");
    if (handle != NULL)
        CloseHandle(handle);
    return 0;
}

and C# code: using System; using System.IO.MemoryMappedFiles;

class Program
{
    static void Main(string[] args)
    {
        MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("MySharedMemory");
        MemoryMappedViewStream mmfvs = mmf.CreateViewStream();
        byte[] blen = new byte[4];
        mmfvs.Read(blen, 0, 4);
        int len = blen[0] + blen[1] * 256 + blen[2] * 65536 + blen[3] * 16777216;
        byte[] strbuf = new byte[len];
        mmfvs.Read(strbuf, 0, len);
        string s = System.Text.Encoding.Default.GetString(strbuf);
        Console.WriteLine(s);
    }
}

just for example.

you may also add error-check part.

Sorayuki
  • 256
  • 2
  • 7
  • sorry I don't understand what you suggest, probably some code may help :) also I do not want to use `P/Invoke` at all as it relatively slow and i'm writing low-latency code. – Oleg Vazhnev Apr 21 '13 at 08:52
  • @javapowered it seems that there is no build-in shared memory feature in .net. References http://stackoverflow.com/questions/439787/how-to-implement-shared-memory-in-net – Sorayuki Apr 21 '13 at 08:58
  • http://stackoverflow.com/questions/4580722/fully-managed-shared-memory-net-implementations – Oleg Vazhnev Apr 21 '13 at 09:04
  • @javapowered I have never known that .net now has build-in shared memory support. Now an example is added to my answer. You may have a look on it. – Sorayuki Apr 21 '13 at 09:22
  • @javapowered because a pointer represent an address of current process. When it comes to inter process communicating, a pointer for process A may not work for process B. So in this example I'm using an in-place array in the struct. Sorry for poor English – Sorayuki Apr 21 '13 at 10:27
  • @javapowered, since you always have to map ANSI <-> UTF16, I suspect your low-latency requirements can't be fulfilled. – Zdeslav Vojkovic Apr 23 '13 at 14:36
  • @ZdeslavVojkovic after some research i've found that i can replace string to just int, so now things will be much simpler, i hope. – Oleg Vazhnev Apr 23 '13 at 14:37
  • Was looking to pass shared memory to pass between two C# apps. It's not working so browsing BUT I did notice that the C# side has an error that wouldn't have showed in this example. When decoding the length of the string, the last component in the line should be blen[3]*... not blen[2]. – shooky Nov 21 '19 at 15:51