托管C ++,未将对象引用设置为对象的实例

时间:2011-09-28 19:54:20

标签: c++-cli managed nullreferenceexception runtime-error

我以前遇到过这个问题,但从来没有遇到这样的情况。我完全糊涂了。正如问题所述,我收到运行时错误“对象引用未设置为对象的实例”。使用调试器工具,我想我已经将问题指向了这一行:

dataFileLocation = path;

整个功能在这里:

void DATReader::SetPath(String^ path) 
{
    if(!File::Exists(path))
    {
        MessageBox::Show( "DATReader (missing dat file: \n"+path+"\n )", "Error", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
        return;
    }
    dataFileLocation = path;
}

dataFileLocation在这里声明,但没有分配给它:

ref class DATReader
{
private:
    System::String^ dataFileLocation;
    // ...
}

现在我知道我收到错误的原因是因为dataFileLocation没有分配。但我在分配它时遇到了问题。当我向它添加= 0;时,它将不会构建,因为它是一个ref类。当我尝试将其分配给构造函数中的= 0;时,它会因为尝试将其从System::String^转换为int而对我大喊大叫。如果我将它分配给它构建的= gcnew String("");,但会抛出相同的运行时异常。

我不明白,我读错了调试器,这根本不是问题的根源吗?我最近刚开始使用托管代码,所以我很困惑:\

3 个答案:

答案 0 :(得分:3)

您可能需要检查并确保您的DATReader对象也不为空它可能会在您的DATReader.SetPath()调用中抛出异常。

答案 1 :(得分:2)

在C ++中,这是C ++ / CLI中缺少的。 C#生成的代码确保永远不会为null。通过在方法上设置断点并检查“this”,可以在调试器中轻松查看。这是一个重现异常的示例程序:

#include "stdafx.h"

using namespace System;

ref class Example {
    String^ dataFileLocation;
public:
    void SetPath(String^ path) { 
        dataFileLocation = path;   // Set breakpoint here and inspect "this"
    }
};

int main(array<System::String ^> ^args)
{
    Example^ obj /* = gcnew Example */;
    obj->SetPath("foo");
    return 0;
}

删除要修复的/ * * /注释。通过查看调用堆栈来找到忘记实例化对象的方法来修复代码。

答案 2 :(得分:1)

托管C ++使用nullptr进行空引用。所以你可以查看:

if (path == nullptr) { ... }

或使用:

if (!String::IsNullOrEmpty(path))