2012-11-08 110 views
1

摘要:AccessViolationException从本地DLL访问内存时

我写汇编小游戏引擎和我在一个类中通过的DllImport我的C#项目使用导出的函数从我的引擎DLL。目前为止一切正常,但是我在执行我的LoadTexture函数时不断收到AccessViolationException

它的意思是通过.NET框架位图类加载纹理,并将第一个像素数据(mybitmap.Scan0)的地址传递给我的本机DLL,然后再呈现我的纹理。但是,只要本机代码尝试从此内存地址访问数据,就会得到AccessViolationException

这是这个函数的我的DllImport代码看起来是这样的:

[System.Runtime.InteropServices.DllImportAttribute("engine.dll", 
    CharSet = CharSet.Ansi, 
    CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall, 
    ExactSpelling = true), 
    System.Security.SuppressUnmanagedCodeSecurity 
] 
private static extern void LoadTexture(int width, int height, IntPtr handle); 

这是C#代码调用我的原生功能:

public static void LoadTexture(string file) 
{ 
    Bitmap bitmap = new Bitmap(file); 

    BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, 
    bitmap.Width, bitmap.Height), 
    ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 

    LoadTexture(data.Width, data.Height, data.Scan0); 
} 

问题:

  • 我的DllImport语句可能有错误或者它看起来好吗?

  • 这个问题的原因是什么?

如果您需要更多的信息可能有助于解决我的问题,请不要犹豫,在评论中问我。

+2

你写*汇编代码*,并认为该函数[DllImport]可能会造成问题?你需要调试这个。 –

+0

那么我的asm代码工作正常,如果我导入libpng并只加载我的纹理与这个库(根本没有任何C#代码),但现在我很乐意加载与.net框架的纹理,而不是因为它真的支持许多不同的格式。我也为asm解码器制作了一些基本的图像格式,但我认为它们还不够稳定。 – beta

+1

当我得到AVE时,我无法跟踪我启动[Application Verifier](http://msdn.microsoft.com/en-us/library/ms220948)并附加WinDbg。这样,如果这是我的C++代码段,WinDbg将在违规代码中破解。如果它不是我的代码,那么很可能DllImport是错误的,我使用[MDAs](http://msdn.microsoft.com/en-us/magazine/cc163606.aspx)来帮助(例如PInvokeStackImbalance)。 –

回答

2

您是否已将纹理位图锁定到内存中?玩指针前需要使用Bitmap.LockBits()

http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx

+0

感谢您的回答,并遗憾地忘记发布我调用本地函数的C#代码部分(是的,在调用我的本地函数之前调用LockBits)。到目前为止,我尝试了两种方法,使用ReadOnly和ReadWrite锁定模式,但不幸的是我还没有成功。 – beta

+1

哦,好的。我必须建议你的LoadText功能是错误的。 Scan0返回的扫描行格式可能与预期的不同。它是否考虑到了Stride和PixelFomat,请参阅http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx –

+0

愚蠢的我!我将项目类型从AnyCPU更改为x86,现在它完美无瑕地工作......花了我几天的时间来弄清楚。非常感谢您对我的问题进行调查! – beta