尝试将托管数据放入glTexImage3D时AccessViolationException

时间:2013-05-24 09:41:53

标签: visual-studio-2010 opengl memory-management casting c++-cli

尝试将一些数据读入opengl纹理时出错。我的错误如下:

A first chance exception of type 'System.AccessViolationException' occurred in libCoin3D.dll

当我在下面的函数中调用函数glTexImage3D时会发生这种情况。如果我注释掉该函数,那么程序运行正常,但我需要从int数组构造一个纹理,我传入函数。

GLuint TextureHandler::create3DTextureBonePreview(int* d, Vector3 length){
    GLuint bindLocation;
    glGenTextures(1, &bindLocation);


    static_cast<char*>(static_cast<void*>(d));

    int w=length.x;
    int h=length.y;
    int l=length.z;
    glBindTexture(GL_TEXTURE_3D, bindLocation);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


    glTexImage3D(GL_TEXTURE_3D, 0,GL_RGBA,w, h, l, 0,GL_RGBA, GL_UNSIGNED_BYTE,d);
    printf("Done creating texture\n");

    return bindLocation;
}

我认为这与我在int * d中处理内存的方式有关。这些数据在一些C#代码中仅作为常规int数组开始,并在不久之后填充。

 int[] allDatint=new int[dataSize];

但是从这个C#中,allDatint被传递给一个Managed C ++构造函数,它将它作为一个系统数组:

CallbackNode::CallbackNode(int w ,int h, int l, array<int>^ d)

在该构造函数中,在将其传递给某些非托管C ++代码之前,它将转换为int *

cli::pin_ptr<int> pArrayElement = &d[0];
mCube=new MasterCube(w,h,l,pArrayElement);

非托管C ++接受它作为int *

MasterCube::MasterCube(int w,int h, int l, int* d)

然后将其传递给上面的函数,首先将其转换为glTexImage3D接受的char数组。

static_cast<char*>(static_cast<void*>(d));

我对AccessViolationException的看法让我相信'int * d'中的数据已损坏或glTexImage3D无法使用。有人可以告诉我,如果我在array / systemArray / int * / char *中转换它是否有问题?或者只是用错误的格式让opengl理解它?

1 个答案:

答案 0 :(得分:1)

  

然后将其传递给上面的函数,首先将其转换为glTexImage3D接受的char数组。

static_cast<char*>(static_cast<void*>(d));

将转换指针分配给的char *ptr在哪里?只是将一个变量放入一个cast语句中就不会“转换”变量。

至于你的实际问题。我很确定表达式w * h * l * 4的值超过实际数组的大小(以字节为单位)。由于那里只有一个裸指针,所以不可能在那里添加一个完整性检查。