내 프로젝트 중 하나에서 P/Invoke를 사용하여 avifil32.dll 메소드를 호출하고 모든 것이 지금까지 제대로 작동했습니다. 오늘, 몇 달 후 그 프로젝트로 돌아가고 그 동안 Windows 8로 전환함으로써, 나는 더 이상 아무것도 작동하지 않는다는 것을 발견했습니다. avifil32 메소드에 대한 대부분의 호출은 AccessViolationException
("보호 된 메모리 읽기 또는 쓰기 시도 ...")를 발생시킵니다. 내가 this 유용한 게시물을 발견하고 결과적으로 웹에 일부 검색 후C# LPCTSTR에서 마샬링이 더 이상 작동하지 않습니다.
[DllImport("avifil32.dll", PreserveSig=true)]
static extern int AVIFileOpen(out IntPtr ppfile, string szFile, uint mode, int pclsidHandler);
:
한 기능이 (또한 pinvoke.net here에 명시된) 이전에 나는이 방법으로 호출 된 AVIFileOpen
이었다으로 하여금 나는 내 호출 (주 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로 넘어 가고 있지만 문제를 설명 할 수 있습니까?
편집
내가 전화를 호출 /를 P를 수정하지했고 지금은 더 이상 AccessViolationexception
을했습니다 한스 옆모습의 sugestion에 따라. 그러나 전에 일하는 동안 그것은 여전히 내게 미스터리입니다. 사실 현재 (Win8)와 이전 (Win7)에는 64 비트 OS가 있습니다. 그러나 프로젝트 설정에서 설명 할 수있는 또 다른 세부 사항이 있습니다. 이것은 내 프로젝트에서 호출 된 라이브러리 프로젝트입니다. 필자의 주요 프로젝트 대상은 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);
전체 코드를 공유 할 수 있습니까? 언젠가 고통으로 이어질 것입니다 –