Chr*_*ris 4 c++ string pinvoke struct marshalling
我在C#和C++应用程序之间编组数据.在C#应用程序中,我强制将字符串的大小设置为某个大小(例如,256字节).我想在C++中读取完全相同的数量(我将使用reinterpret_cast重新创建结构),以便数据保持格式化,就像在C#应用程序中一样.不幸的是,我对C++很生疏,我不确定如何在C++中强制使用字符串的大小.
根据要求,举个例子.我在C#中有一个结构,如下所示:
[StructLayout(LayoutKind.Sequential)]
public struct DataLocater
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string filename;
[MarshalAs(UnmanagedType.I4)]
public Int32 sizeOfData;
public Int32 startLocation;
public Int32 encrypted;
}
Run Code Online (Sandbox Code Playgroud)
我正在将数个(以及其他数据)编组到数据文件中.然后C++文件读取此文件,我将使用相同的结构将其解析回C++中的struct.我对这个结构的第一次尝试看起来像:
struct DataLocater
{
std::string filename;
int sizeOfData;
int startLocation;
int encrypted;
};
Run Code Online (Sandbox Code Playgroud)
但是编译器无法知道我希望std :: string为256字节.
编辑:添加完整的头文件,例如.
#pragma once
#include "CoreArea/Singleton.h"
class FileReader : public Singleton<FileReader>
{
friend class Singleton<FileReader>;
public:
void* GetFileData(std::wstring fileName, int &size);
private:
FileReader();
~FileReader();
struct Header
{
std::string somestring;
int numOfFiles;
};
struct DataLocater
{
char[256] filename;
int sizeOfData;
int startLocation;
int encrypted;
};
};
Run Code Online (Sandbox Code Playgroud)
这是你想要的?
struct DataLocater
{
char filename[256];
int sizeOfData;
int startLocation;
int encrypted;
};
Run Code Online (Sandbox Code Playgroud)
编辑:考虑到你不需要强制任何一个字符串具有一定的大小,你可以声明文件名为char *和在C#大小上你使用一个没有限制的字符串.这样,您只需要使用尽可能多的内存(并且可能使用比您最初估计的更多,避免缓冲区溢出错误).
一般来说,你在这里采取了错误的方法.混合非数据只有C++类型和PInvoke将带来很多痛苦.不应在此方案中使用类似std :: string的类型,因为编组器无法在运行时正确创建它们.
相反,您需要使用更原始的类型.在此特定方案中,基于托管签名,适当的C结构如下
struct DataLocater
{
char filename[256];
int sizeOfData;
int startLocation;
int encrypted;
};
Run Code Online (Sandbox Code Playgroud)