C# WPF计划拒绝DllImport 我有一个WPF应用程序,它运行一个扫描仪(通过C++ COM对象),创建一个(相当大)的TIFF文件并将其存储在磁盘上。大多数重载都是在C++中完成的。
该程序一次扫描大块的页面(比如50页——来自平装书),并将其存储在tiff中 最近,我添加了一些代码,从每个块中带回了几个页面,这样我就可以看到扫描正常工作的迹象 事实证明,这导致了大规模内存泄漏 我很确定这是因为没有处理内存,但在哪里:) 我眼前的问题是,我试图在c#模块内部使用DeleteObject,但它不会编译C# WPF计划拒绝DllImport 我有一个WPF应用程序,它运行一个扫描仪(通过C++ COM对象),创建一个(相当大)的TIFF文件并将其存储在磁盘上。大多数重载都是在C++中完成的。,c#,wpf,interop,pinvoke,dllimport,C#,Wpf,Interop,Pinvoke,Dllimport,该程序一次扫描大块的页面(比如50页——来自平装书),并将其存储在tiff中 最近,我添加了一些代码,从每个块中带回了几个页面,这样我就可以看到扫描正常工作的迹象 事实证明,这导致了大规模内存泄漏 我很确定这是因为没有处理内存,但在哪里:) 我眼前的问题是,我试图在c#模块内部使用DeleteObject,但它不会编译 [System.Runtime.InteropServices.DllImport("gdi32.dll")] private static extern bool Delete
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);
编译器告诉我
命名空间不能直接包含字段或方法等成员
但我看不出我做错了什么
从内存泄漏的大小(20MB)来看,我认为问题出在c#端,但这里有一段代码,以防我遗漏了什么
C++
STDMETHODIMP CWiaDevice::get_Image(SHORT Index, HBITMAP* pVal)
{
if (Index >= mStreams.Count())
{
return E_INVALIDARG;
}
if (Index < 0)
{
return E_INVALIDARG;
}
if (mLastBitmap != NULL)
{
return E_UNEXPECTED;
}
mLastBitmap = Bitmap::FromStream(mStreams[Index]);
Gdiplus::Status status = mLastBitmap->GetHBITMAP(Color::Black, pVal);
if (status != Ok)
return E_FAIL;
return S_OK;
}
STDMETHODIMP CWiaDevice::ReleaseImage()
{
if (mLastBitmap != NULL)
{
delete mLastBitmap;
mLastBitmap = NULL;
}
return S_OK;
}
及
我计划在创建img.Source之后,用上述方法将DeleteObject放在bmp上。我假设我不需要显式地处理我以前创建的img.Source,也看不到任何方法
非常感谢您的帮助
伊恩
命名空间不能直接包含字段或方法等成员
错误消息告诉您不能将方法直接放置在命名空间中。该方法必须位于类中,您可以将该类放置在命名空间中。这是一个静态方法,因此您不需要创建该类的实例,但语言规则意味着您仍然需要这样一个类 方法必须在类内,如果它是c#对象,但它是外部对象,我会得到它。我看到的所有示例都与此完全相同(并且在没有类对象的情况下调用)。不,方法总是在类中。错误消息告诉您这一点。确定。我已经这样做了,并将导入放在一个类中——这已经奏效了。在函数存在的意义上工作,我可以调用它。然而,我在网上看到的所有例子都是按照我最初的方式进行的。好吧。现在看看这是否解决了这个问题不,没有任何例子这样做,因为它无法编译
img = mDevice.Image[0];
SetImage(imgTop, img);
mDevice.ReleaseImage();
private void SetImage(Image img, IntPtr bmp)
{
var options = BitmapSizeOptions.FromEmptyOptions();
img.Source = Imaging.CreateBitmapSourceFromHBitmap(bmp, IntPtr.Zero, Int32Rect.Empty, options);
img.InvalidateMeasure();
}