Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.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+的AccessViolationException+/CLI和本机互操作 我有一个CLI/C++类实例化一个本地C++对象,然后在那个对象上调用一个方法,并返回一些数据。我收到了随机的AccessViolationExceptions,无法了解发生了什么。以下是我的代码的精简版本: public ref class MyWrapper { public: MyWrapper() { nativeObject = new NativeObject(); } Object^ getData(String^ field) { string nativeField = msclr::interop::marshal_as<string>(field); Data nativeResult = nativeObject->getData(nativeField); Object^ result = convertToManaged(nativeResult); return result; } Object& convertToManaged(Data data) { // This converts the char* noted below back into its basic data type, and returns it as an object } private: NativeObject* nativeObject; }_C++_C++ Cli - Fatal编程技术网

带有C+的AccessViolationException+/CLI和本机互操作 我有一个CLI/C++类实例化一个本地C++对象,然后在那个对象上调用一个方法,并返回一些数据。我收到了随机的AccessViolationExceptions,无法了解发生了什么。以下是我的代码的精简版本: public ref class MyWrapper { public: MyWrapper() { nativeObject = new NativeObject(); } Object^ getData(String^ field) { string nativeField = msclr::interop::marshal_as<string>(field); Data nativeResult = nativeObject->getData(nativeField); Object^ result = convertToManaged(nativeResult); return result; } Object& convertToManaged(Data data) { // This converts the char* noted below back into its basic data type, and returns it as an object } private: NativeObject* nativeObject; }

带有C+的AccessViolationException+/CLI和本机互操作 我有一个CLI/C++类实例化一个本地C++对象,然后在那个对象上调用一个方法,并返回一些数据。我收到了随机的AccessViolationExceptions,无法了解发生了什么。以下是我的代码的精简版本: public ref class MyWrapper { public: MyWrapper() { nativeObject = new NativeObject(); } Object^ getData(String^ field) { string nativeField = msclr::interop::marshal_as<string>(field); Data nativeResult = nativeObject->getData(nativeField); Object^ result = convertToManaged(nativeResult); return result; } Object& convertToManaged(Data data) { // This converts the char* noted below back into its basic data type, and returns it as an object } private: NativeObject* nativeObject; },c++,c++-cli,C++,C++ Cli,数据的粗略定义: class Data { private: string field; int dataType; char* dataArray; size_t size; public: Data() { dataArray = NULL; } Data(const Data &value) { copyData(value); } ~Data() { delete d

数据的粗略定义:

class Data
{
private:
   string field;
   int dataType;
   char* dataArray;
   size_t size;

public:
   Data()
   {
      dataArray = NULL;
   }
   Data(const Data &value) 
   {
      copyData(value);
   }

   ~Data()
   {
      delete dataArray;
   }

   void copyData(const Data &value)
   { 
      dataType = value.dataType;
      size = value.size;

      if (value.dataArray != NULL)
      {
         dataArray = new char[value.size];
         memcpy(dataArray, value.dataArray, value.size);
      }
      else
      {
         dataArray = NULL;
      }
   }

   Data& Data::operator=(const Data & value)
   {
      copyData(value);
      return *this;
   }

   void addData()
   {
      /* This converts a basic data type like a double into a char* with reinterpret_cast, 
      like this: 

      double* newValue = new double();
      *newValue = value;
      dataArray = reinterpret_cast<char*>(newValue);
      size = sizeof(double);
      */
   }
}
类数据
{
私人:
字符串字段;
int数据类型;
字符*数据数组;
大小;
公众:
数据()
{
dataArray=NULL;
}
数据(常量数据和值)
{
复制数据(值);
}
~Data()
{
删除数据数组;
}
无效复制数据(常量数据和值)
{ 
数据类型=value.dataType;
大小=value.size;
if(value.dataArray!=NULL)
{
dataArray=新字符[value.size];
memcpy(dataArray,value.dataArray,value.size);
}
其他的
{
dataArray=NULL;
}
}
数据和数据::运算符=(常量数据和值)
{
复制数据(值);
归还*这个;
}
void addData()
{
/*这会将double之类的基本数据类型转换为具有reinterpret_cast的char*,
这样地:
double*newValue=newdouble();
*newValue=值;
dataArray=reinterpret\u cast(newValue);
尺寸=sizeof(双倍);
*/
}
}
大多数情况下,这种方法很好用。我有一个C#测试程序集,它使用各种(预期的)输入类型运行它,并且运行时没有问题。但是,当我把它放在一个更大的应用程序上下文中时,它会随机抛出AccessViolationExceptions。虽然它们中的大多数都来自这段代码本身,但并不总是在同一个地方——有时是托管getData函数,有时是本机getData函数。更奇怪的是,当使用此代码运行时,应用程序中纯管理的随机其他部分将给我AccessViolationException,这在添加此代码之前从未发生过

知道发生了什么事吗?很明显,我的记忆力有问题,但我不知道是什么。我尝试了一些变化(将本机数据对象作为指针返回,从托管代码中创建结果对象作为pin_ptr,并将其作为参数传递,等等),但它们都会产生类似的结果


注释掉result.addData()似乎可以消除这个问题。该方法所做的只是分配一些存储在dataArray字段中的内存。然后将其传递回托管代码这一事实可能是问题所在吗?

您为
数据
类提供的复制构造函数为空,因此,无论何时进行复制,您都在创建一个对象,而不是要复制的对象的副本。发生的情况是,您的程序现在正在传递未完成的副本,而没有
dataArray
元素集

这些错误(用户定义的复制构造函数已损坏或不完整)是最难诊断的错误之一。必须完成代码,复制构造函数才能执行真正的复制

此外,您还需要一个赋值运算符来完成“规则3”

编辑:正确编码的副本构造函数示例如下:

   Data(const Data &value) : field(value.field), dataType(value.dataType), dataArray(0) 
   {
     addData(dataType, value.dataArray);
   }
并在
addData
中确定数据类型

其他信息:

析构函数不需要检查NULL,因为它不是必需的

~Data()
{
    delete dataArray;
}
此外,赋值运算符将如下所示:

   #include <algorithm>
   //...
   Data& operator=(Data value)
   {
      std::swap(value.dataType, dataType);
      std::swap(value.dataArray, datArraye);
      std::swap(value.field, field);
      return *this;
   }
#包括
//...
数据和运算符=(数据值)
{
std::swap(value.dataType,dataType);
std::swap(value.dataArray,datArraye);
标准::交换(value.field,field);
归还*这个;
}

Google“c++三规则”,您使用dataArray成员违反了该规则。函数的作用是致命的。可能不是唯一的地方。你是说我缺少复制构造函数和析构函数吗?我确实有这些-对不起,应该包括它们。@Deeko-规则3也需要赋值运算符。第二,你的复制构造函数是假的。它什么也不做,也不复制。这种虚假性足以导致像你这样的复制程序出现问题。你能解释一下是什么导致它是虚假的吗?我将其转换回值类型,为新对象创建一个新指针,然后将该值放入该指针中。“少了一步吗?”@Deeko-见下面我的答案。您的复制构造函数的责任是复制。你的代码拒绝这样做。它不是空的。注释掉的部分解释了它的功能。我可以把所有的东西都填好,但那没用。数据类在不同的数据类型上运行,并根据特定的输入,将dataArray转换为不同的原语。在这里输入所有内容并不会增加问题的内容,所以我举了一个例子,说明它对双打的作用。@Deeko-请编辑您的问题。当你发布代码时,我们要做的就是你发布的内容。如果我们没有看到实现,那么就没有实现。是的,你发布它是很重要的,因为你的代码调用了复制构造函数。很抱歉不清楚-我确实在复制构造函数中发布了代码,但是在一个注释中,因为不是每种情况都完整。我对原始问题进行了编辑以反映这一点,但是,正如新的评论所说,“else”案例实际上填写了dataArray,就像它填写double的方式一样,只是填写了其他数据类型。@Deeko-复制构造函数的唯一职责是创建一个副本。我不能再强调这个了。您的实现充其量是不可靠的。您根本不应该执行任何if语句——只需获取传递给您的对象,并创建它的精确副本。如果你不这样做,那么我的答案是——你可能会传递一些半生不熟的副本。你用新的代码更新了你的问题。您的赋值运算符现在有故障。请使用我在上面的答案中发布的答案。或者更好的方法是使用
std::vector
,这样就不需要assig了
   #include <algorithm>
   //...
   Data& operator=(Data value)
   {
      std::swap(value.dataType, dataType);
      std::swap(value.dataArray, datArraye);
      std::swap(value.field, field);
      return *this;
   }