Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++/CLI(.NET)相当于本机C++;网络写作结构 我最近继承了一个混合C++和C++ +CLI(.NET)的程序。它通过网络连接到其他组件,并连接到一些特殊硬件的驱动程序DLL。然而,我正试图找出通过网络发送数据的最佳方式,因为所使用的方式似乎不是最优的 < >数据存储在C++定义的结构中,例如: struct myCppStructure { unsigned int field1; unsigned int field2; unsigned int dataArray[512]; };_C++_Performance_Data Structures_Network Programming_C++ Cli - Fatal编程技术网

C++/CLI(.NET)相当于本机C++;网络写作结构 我最近继承了一个混合C++和C++ +CLI(.NET)的程序。它通过网络连接到其他组件,并连接到一些特殊硬件的驱动程序DLL。然而,我正试图找出通过网络发送数据的最佳方式,因为所使用的方式似乎不是最优的 < >数据存储在C++定义的结构中,例如: struct myCppStructure { unsigned int field1; unsigned int field2; unsigned int dataArray[512]; };

C++/CLI(.NET)相当于本机C++;网络写作结构 我最近继承了一个混合C++和C++ +CLI(.NET)的程序。它通过网络连接到其他组件,并连接到一些特殊硬件的驱动程序DLL。然而,我正试图找出通过网络发送数据的最佳方式,因为所使用的方式似乎不是最优的 < >数据存储在C++定义的结构中,例如: struct myCppStructure { unsigned int field1; unsigned int field2; unsigned int dataArray[512]; };,c++,performance,data-structures,network-programming,c++-cli,C++,Performance,Data Structures,Network Programming,C++ Cli,当从C++/CLI访问结构本身时,程序工作正常。问题在于,要通过网络发送,当前代码会执行以下操作: struct myCppStructure* data; IntPtr dataPtr(data); // myNetworkSocket is a NetworkStream cast as a System::IO::Stream^ System::IO::BinaryWriter^ myBinWriter = gcnew BinaryWriter(myNetw

当从C++/CLI访问结构本身时,程序工作正常。问题在于,要通过网络发送,当前代码会执行以下操作:

    struct myCppStructure* data;
    IntPtr dataPtr(data);
    // myNetworkSocket is a NetworkStream cast as a System::IO::Stream^
    System::IO::BinaryWriter^ myBinWriter = gcnew BinaryWriter(myNetworkSocket);
    __int64 length = sizeof(struct myCppStructure) / sizeof(__int64);
    unsigned __int64* ptr = static_cast<__int64*>(dataPtr.toPointer());
    for (unsigned int i = 0; i < (length / sizeof(unsigned __int64)); i++)
        myBinWriter->Write((*ptr)++);
但是我在C++/CLI中找不到任何等价的东西。System::IO::BinaryWriter只有基本类型和其中一些类型的一些数组版本。没有比这更有效的了吗

注意:这些记录每秒生成多次;因此,进行额外的复制(例如封送)是不可能的


注:原来的问题是关于C#的。我没有意识到我所认为的C#实际上是.NET下的“托管C++”(又名C++/CLI)。上面已经编辑了用“c++/CLI”引用替换“C++”引用,我使用的是任何版本的托管C++,尽管我特别注意使用.NET 3.5。

您要做的是找出C++结构是如何打包的,并定义一个结构正确的属性。< /P> 要定义固定长度int[],可以在其内部定义一个。请注意,要使用此选项,您必须将项目标记为“不安全”

现在,您可以使用两个步骤将该结构转换为字节[]

  • 使用a将结构数组固定在内存中-这很快,不应该成为性能瓶颈
  • 现在使用源IntPtr=(不要担心,这和memcpy一样快)
  • 现在处理GCHandle,就可以使用Serg Rogovtsev提到的方法写入字节了


    希望这有帮助

    您的结构由“基本类型”和“它们的数组”组成。为什么不能使用
    BinaryWriter
    按顺序编写它们呢?差不多

    binWriter.Write(data.field1);
    binWriter.Write(data.field2);
    for(var i = 0; i < 512; i++)
        binWriter.Write(data.dataArray[i]);
    
    binWriter.Write(data.field1);
    binWriter.Write(data.field2);
    对于(变量i=0;i<512;i++)
    Write(data.dataArray[i]);
    
    在C语言中,您可以执行以下操作。从定义结构开始

    [StructLayout ( LayoutKind.Sequential )]
    internal unsafe struct hisCppStruct
    {
        public uint field1;
        public uint field2;
        public fixed uint dataArray [ 512 ];
    }
    
    然后使用二进制编写器编写它,如下所示

    hisCppStruct @struct = new hisCppStruct ();
    @struct.field1 = 1;
    @struct.field2 = 2;
    @struct.dataArray [ 0 ] = 3;
    @struct.dataArray [ 511 ] = 4;
    
    using ( BinaryWriter bw = new BinaryWriter ( File.OpenWrite ( @"C:\temp\test.bin") ) )
    {
        int structSize = Marshal.SizeOf ( @struct );
        int limit = structSize / sizeof ( uint );
    
        uint* uintPtr = (uint*) &@struct;
    
        for ( int i = 0 ; i < limit ; i++ )
            bw.Write ( uintPtr [ i ] );
    }
    
    hisCppStruct@struct=new-hisCppStruct();
    @struct.field1=1;
    @struct.field2=2;
    @struct.dataArray[0]=3;
    @struct.dataArray[511]=4;
    使用(BinaryWriter bw=新的BinaryWriter(File.OpenWrite(@“C:\temp\test.bin”))
    {
    int structSize=Marshal.SizeOf(@struct);
    int limit=structSize/sizeof(uint);
    uint*uintpttr=(uint*)和@struct;
    对于(int i=0;i

    我确信你在管理C++中可以做同样的事情。< / P>请注意我在原来的文章中说Marshaling不是一个选项。我知道数据是如何包装的;它已经被包装在一个C#结构中了,但据我所知,并不像你所描述的那样。(我对C#很陌生,所以我可能错了。)另外,你没有回答我关于如何在网络上发送信息的问题。System::IO::BinaryWriter使用数组^objects,而不仅仅是byte[]数组。@很抱歉,但你错了:@SergRogovtsev-有趣的是,你链接到了我刚才提到的一个函数。它使用数组^对象,而不是字节[]数组。@临时用户是否可以编辑您的问题,因此它不引用C++代码中的C??因为C是内存管理的,所以您不能像C++中那样访问内存指针。这意味着,如果不先创建对象的可访问字节表示,就无法直接访问对象的字节表示以发送逐字节副本。您必须先将对象转换为一系列字节,然后使用BinaryWriter通过网络发送对象,以准备传输(即封送数据)。您确定需要进入这个兔子洞吗?我们已经考虑改写它来摆脱C,因为它使用了CORE2 DIO 2GHZ +处理器的75-80%,C和C++之间的中继是一个很大的贡献者。看看代码,上面列出的循环也是一个很大的贡献因素——特别是当C#/.NET调用的低级API能够通过简单地指定缓冲区的长度来发送缓冲区时(例如WinSock,根据文档,NetStream应该基于WinSock)。它只是语言和VM设计,支持本地接口,但却不支持他们。这是“比特攻击”的最佳选择。@暂时存在,而不是把它变成C++与C的辩论,让我们看看是什么基础结构支持比特攻击。我在下面提供的(新)解决方案只有一个额外的memcpy,如果不使用BinaryWriter,可以避免将数据直接复制到套接字;但是有很多不同的。还有几个不同的结构正在发送,我不希望每个结构类型有不同的编写器。Simple通常更好,在这种情况下,C和C++非常简单的方法工作得非常好,性能也非常好。我不明白为什么C#没有一个好的、容易找到的等价物。事实上,它有。它被称为
    BinarySerializer
    。您必须了解,C#被设计为非常高级的语言,因此它不需要任何特定的内存布局。因此,内存算法通常在那里不起作用。您可能可以在运行时使用反射来确定字段,并创建一个可以处理任何类型结构的编写器。@Kibbee这就是
    BinarySerializer
    所做的。@SergRogovtsev-从C++/CLI文档中可以看出,BinarySerializer不可用()。它是针对VB和C语言的,而不是C++的。在TemporalB的例子中,我试图消除这个循环——BW。Wr.()。
    hisCppStruct @struct = new hisCppStruct ();
    @struct.field1 = 1;
    @struct.field2 = 2;
    @struct.dataArray [ 0 ] = 3;
    @struct.dataArray [ 511 ] = 4;
    
    using ( BinaryWriter bw = new BinaryWriter ( File.OpenWrite ( @"C:\temp\test.bin") ) )
    {
        int structSize = Marshal.SizeOf ( @struct );
        int limit = structSize / sizeof ( uint );
    
        uint* uintPtr = (uint*) &@struct;
    
        for ( int i = 0 ; i < limit ; i++ )
            bw.Write ( uintPtr [ i ] );
    }