【问题标题】:passing c++ char* to c# via shared-memory通过共享内存将 c++ char* 传递给 c#
【发布时间】:2013-04-21 07:59:44
【问题描述】:

抱歉,这个问题可能很简单,但我是共享内存的新手,并试图通过示例学习如何做事。

在 c++ 方面,我收到这样的一对:const unsigned char * value, size_t length 在 c# 方面,我需要有常规的 c# 字符串。使用共享内存的最佳方法是什么?

【问题讨论】:

    标签: c# c++ shared-memory


    【解决方案1】:

    使用字符串并不容易。

    如果是我,我会尝试这些方法:

    1. 只需获取字符串的副本。 System.Text.Encoding.Default.GetString 可以从字节数组转换为字符串。

    你可以尝试在一个不安全的代码块中(因为你可以使用指针类型)来做:

    (1) 创建一个字节数组,大小就是你的“长度”

    字节[] buf = 新字节[长度];

    (2) 将数据复制到数组中

    for(int i = 0; i

    (3) 获取字符串

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

    2.编写一个类,有一个属性“string what_you_want”,每次访问都会执行上述过程。

    首先,您应该首先使用 P/Invoke 功能来获取该对的值。

    编辑:这是一个例子。

    C++ 代码:

    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;
    }
    

    和 C# 代码: 使用系统; 使用 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);
        }
    }
    

    只是举例。

    您还可以添加错误检查部分。

    【讨论】:

    • 对不起,我不明白你的建议,可能一些代码可能会有所帮助:) 我也不想使用P/Invoke,因为它相对较慢而且我正在编写低延迟代码.
    • @javapowered .net 中似乎没有内置共享内存功能。参考stackoverflow.com/questions/439787/…
    • @javapowered 我从来不知道.net 现在有内置的共享内存支持。现在在我的答案中添加了一个示例。你可以看看它。
    • @javapowered 因为指针代表当前进程的地址。当涉及进程间通信时,进程 A 的指针可能不适用于进程 B。所以在这个例子中,我在结构中使用了就地数组。抱歉英语不好
    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多