我在我的一個項目中使用P/Invoke來調用avifil32.dll方法,並且一切正常。今天,幾個月後又回到了這個項目,並在此期間切換到Windows 8,我發現沒有任何工作了。我對avifil32方法的大多數調用導致AccessViolationException
(「試圖讀取或寫入受保護的內存......」)。編組從c#LPCTSTR不再工作
一個功能使這是AVIFileOpen
,這在以前我用這種方式調用(如在pinvoke.net here還指出):
[DllImport("avifil32.dll", PreserveSig=true)]
static extern int AVIFileOpen(out IntPtr ppfile, string szFile, uint mode, int pclsidHandler);
網絡上的一些搜索後,我發現this有益的職位,因此我改變了我的調用(注AVIFileOpenW):
[DllImport("avifil32.dll", PreserveSig=true, CharSet = CharSet.Auto)]
public static extern int AVIFileOpenW(ref int ppfile, [MarshalAs(UnmanagedType.LPWStr)] String szFile, int uMode, int pclsidHandler);
,現在它的工作原理。不過,我還有其他問題,例如我在呼叫AVIFileCreateStream
的呼叫上有同樣的例外,那麼我在做什麼錯了?更有趣的是,這可能是導致現在什麼都不能工作的原因?我承認我不知道在此期間會發生什麼。從Windows 7到Windows 8發生了巨大變化,但這能解釋這個問題嗎?
編輯
繼漢斯帕桑特sugestion我已經糾正了P/Invoke調用,現在我已經沒有更多的AccessViolationexception
。然而,在工作之前,它對我來說仍然是一種莫名其妙的感覺。事實上,現在(Win8)和之前(Win7)我都有64位操作系統。 但是在項目設置中還有另外一個細節可以幫助解釋。這是一個從我的主項目中調用的庫項目。我的主要項目的目標是x64(針對x86不是一種選擇),而該庫的目標是AnyCPU。我做了另一次試驗,並再次使用這些設置,我的老版本的AVIFileOpen
稱該程序在Win7 x64機器下運行,但不在Win8 x64下運行。這可以通過JIT編譯器與AnyCPU的不同「管理」相關聯,還是必須存在一些我缺少的其他設置?
現在,該程序在x86和x64中均可運行。這裏下面的代碼的摘錄我使用:
AVIFileInit();
IntPtr aviFile = IntPtr.Zero;
IntPtr aviStream = IntPtr.Zero;
string tmp = Path.GetTempFileName();
if (AVIFileOpen(out aviFile, tmp.Substring(0, tmp.Length - 4) + ".avi", OF_WRITE | OF_CREATE, IntPtr.Zero) == 0)
{
AVISTREAMINFO strhdr = new AVISTREAMINFO();
strhdr.fccType = mmioStringToFOURCC("vids", 0);
strhdr.fccHandler = mmioStringToFOURCC("CVID", 0);
strhdr.dwScale = 1;
strhdr.dwRate = 25;
strhdr.dwSuggestedBufferSize = 102400;
strhdr.dwQuality = -1;
strhdr.rcFrame.bottom = 320;
strhdr.rcFrame.right = 320;
strhdr.szName = "";
if (AVIFileCreateStream(aviFile, out aviStream, ref strhdr) == 0)
{
AVICOMPRESSOPTIONS_CLASS options = new AVICOMPRESSOPTIONS_CLASS();
options.fccType = (uint)streamtypeVIDEO;
options.lpParms = IntPtr.Zero;
options.lpFormat = IntPtr.Zero;
bool ok = AVISaveOptions(this.Handle, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, ref aviStream, ref options);
}
}
public static readonly int streamtypeVIDEO = mmioFOURCC('v', 'i', 'd', 's');
public const UInt32 ICMF_CHOOSE_KEYFRAME = 0x0001;
public const UInt32 ICMF_CHOOSE_DATARATE = 0x0002;
public const UInt32 ICMF_CHOOSE_PREVIEW = 0x0004;
public const int OF_WRITE = 1;
public const int OF_READWRITE = 2;
public const int OF_CREATE = 4096;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public UInt32 left;
public UInt32 top;
public UInt32 right;
public UInt32 bottom;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct AVISTREAMINFO
{
public Int32 fccType;
public Int32 fccHandler;
public Int32 dwFlags;
public Int32 dwCaps;
public Int16 wPriority;
public Int16 wLanguage;
public Int32 dwScale;
public Int32 dwRate;
public Int32 dwStart;
public Int32 dwLength;
public Int32 dwInitialFrames;
public Int32 dwSuggestedBufferSize;
public Int32 dwQuality;
public Int32 dwSampleSize;
public RECT rcFrame;
public Int32 dwEditCount;
public Int32 dwFormatChangeCount;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public String szName;
}
[StructLayout(LayoutKind.Sequential)]
public class AVICOMPRESSOPTIONS_CLASS
{
public UInt32 fccType;
public UInt32 fccHandler;
public UInt32 dwKeyFrameEvery;
public UInt32 dwQuality;
public UInt32 dwBytesPerSecond;
public UInt32 dwFlags;
public IntPtr lpFormat;
public UInt32 cbFormat;
public IntPtr lpParms;
public UInt32 cbParms;
public UInt32 dwInterleaveEvery;
}
[DllImport("avifil32.dll")]
public static extern void AVIFileInit();
[DllImport("winmm.dll", CharSet = CharSet.Auto)]
public static extern int mmioStringToFOURCC([MarshalAs(UnmanagedType.LPWStr)] String sz, int uFlags);
[DllImport("avifil32.dll", PreserveSig = true, CharSet = CharSet.Auto)]
public static extern int AVIFileOpen(out IntPtr ppfile, String szFile, int uMode, IntPtr pclsidHandler);
[DllImport("avifil32.dll", CharSet = CharSet.Auto)]
public static extern int AVIFileCreateStream(IntPtr pfile, out IntPtr ppavi, ref AVISTREAMINFO ptr_streaminfo);
[DllImport("avifil32.dll")]
public static extern bool AVISaveOptions(IntPtr hwnd, UInt32 uiFlags, Int32 nStreams, ref IntPtr ppavi, ref AVICOMPRESSOPTIONS_CLASS plpOptions);
你能分享整個代碼嗎? –