我只是试图在我的两个应用程序之间来回发送数据包,但我的字符串在c++中无法通过。这是我在c#做的事情
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size=32)]
public struct Packet
{
public uint packet_type;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_name;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string template_name;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_name_list;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_buffer;
}
var data = new Packet
{
packet_type = (uint)action,
file_name = fileName + Char.MinValue,
file_name_list = "" + Char.MinValue,
template_name = "" + Char.MinValue
};
byte[] buffer = new byte[Marshal.SizeOf(typeof(Packet))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
handle.Free();
var bytesSent = _client.Client.Send(buffer);
byte[] buffer = new byte[Marshal.SizeOf(typeof(Packet))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
handle.Free();
var bytesSent = _client.Client.Send(buffer);这是我在c++上得到的
struct Packet {
unsigned int packet_type;
char* file_name;
char* template_name;
char* file_name_list;
char* file_data;
void serialize(char * data) {
memcpy(data, this, sizeof(Packet));
}
void deserialize(char * data) {
memcpy(this, data, sizeof(Packet));
}
};
char network_data[MAX_PACKET_SIZE];
recv(curSocket, buffer, MAX_PACKET_SIZE, 0);唯一可行的值是packet_type,它是结构中的第一个。那个总是能通过的。我遗漏了什么?
发布于 2014-04-19 08:03:49
尽管我从未尝试过这样的方法,但我认为您不能简单地使用winsock在两个不同的应用程序之间共享数据,然后只传递指针。内存在两者之间受到保护。
您将需要将数据序列化为内存流。对字符串使用适当的类和编码等。然后在您的C++应用程序中反序列化它。
为您的c#应用程序尝试下面这样的操作,然后在您的c++中执行逆操作,它将工作。相反,首先要读取这4个字节,然后告诉我们需要为字符串读取多少.读字符串..。继续到下一个,直到找到文件标记结束为止。
string myString = "abc";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(myString);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
ms.Write(buffer, 0, buffer.Length);
//... rest of code...
}发布于 2014-04-19 07:24:10
你有几个问题:
Size字段中的StructureLayoutchar而不是wchar_t,在C#端有Unicode字符串。sizeof(Packet)为20。memcpy在数据包结构之外复制
在C++中,数据包应定义为:
struct Packet {
unsigned int packet_type;
wchar_t file_name[8];
wchar_t template_name[8];
wchar_t file_name_list[8];
wchar_t file_data[8];
// ...
};发布于 2014-04-19 09:47:34
问题是您将字符串作为指针传递。指针仅在同一进程中有效。如果您的C#是2.0或更高版本,请将您的结构更改为:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Packet
{
public uint packet_type;
public fixed char file_name[??];
public fixed char template_name[??];
public fixed char file_name_list[??];
public fixed char file_buffer[??];
}#pragma pack(push, 1)
struct Packet {
unsigned int packet_type;
wchar_t file_name[??];
wchar_t template_name[??];
wchar_t file_name_list[??];
wchar_t file_data[??];
void serialize(char * data) {
memcpy(data, this, sizeof(Packet));
}
void deserialize(char * data) {
memcpy(this, data, sizeof(Packet));
}
};
#pragma pack(pop)用您想要的大小替换??,C#和C++都必须是相同的大小。不要忘记在每个字符串的末尾添加空字符。
https://stackoverflow.com/questions/23166974
复制相似问题