C++/CLI(.NET)相当于本机C++;网络写作结构 我最近继承了一个混合C++和C++ +CLI(.NET)的程序。它通过网络连接到其他组件,并连接到一些特殊硬件的驱动程序DLL。然而,我正试图找出通过网络发送数据的最佳方式,因为所使用的方式似乎不是最优的 < >数据存储在C++定义的结构中,例如: struct myCppStructure { unsigned int field1; unsigned int field2; unsigned int dataArray[512]; };
当从C++/CLI访问结构本身时,程序工作正常。问题在于,要通过网络发送,当前代码会执行以下操作: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
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[],可以在其内部定义一个。请注意,要使用此选项,您必须将项目标记为“不安全” 现在,您可以使用两个步骤将该结构转换为字节[]
希望这有帮助 您的结构由“基本类型”和“它们的数组”组成。为什么不能使用
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 ] );
}