좋아, 이건 내가 미쳤다. C#에서 C lib 용 포트를 만들고 있지만 바이트 배열 (lib 디렉토리에서 필요함)을 사용하여 비트 맵 (gdi로 생성 됨)을 사용할 때 문제가 발생했습니다.C DLL에 대한. NET 래퍼, 특히 lglcd (g19 sdk)
여기에 코드가 있습니다. pastie) 파일에 나누어 :
- Lglcd.dll : http://pastie.org/1424596 (컴파일)
- G19dotNet.dll : http://pastie.org/1424600 (컴파일, 이 C#을위한 상호 운용성 LIB)
- TestProject입니다 : ,532은 10 (116)
res = LgLcd.NativeMethods.lgLcdUpdateBitmap(openContext.device, ref bmp.hdr, LgLcd.NativeConstants.LGLCD_SYNC_UPDATE(LgLcd.NativeConstants.LGLCD_PRIORITY_NORMAL));
이 잘못된 메모리 액세스에 대해 예외가 발생합니다 라인, 문제는 마지막 파일 (다른 두 꽤 간단합니다)에
( 를 컴파일하지만, 예외를 throw) 관리되는 메모리로.
함수의 서명은 이것이다 : 두 번째 PARAM을 볼 수 있듯이
/// Return Type: DWORD->unsigned int
///device: int
///bitmap: lgLcdBitmapHeader*
///priority: DWORD->unsigned int
[System.Runtime.InteropServices.DllImportAttribute("LgLcd", EntryPoint = "lgLcdUpdateBitmap")]
public static extern uint lgLcdUpdateBitmap([System.Runtime.InteropServices.In] int device, [System.Runtime.InteropServices.In] ref lgLcdBitmapHeader bitmap, [System.Runtime.InteropServices.In] uint priority);
가 lgLcdBitmapHeader에 대한 포인터입니다,하지만 (내가 lib 디렉토리의 이전 버전을 본 적이 있기 때문에) 나는 가정이 이 포인터는하지만 정말,이 문제를 해결하기 위해
여기을 관리 할 수 없습니다,
내가 문제가 있다고 생각 (다른 크기의 구조체 임) lgLcdBitmapQVGAx32 포인터에 주조되어 구조체의 서명입니다 :
012 3,516,[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct lgLcdBitmapHeader
{
/// DWORD->unsigned int
public uint Format;
}
나는 누군가가 나를 도울 수 있기를 바랍니다
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct lgLcdBitmap160x43x1
{
/// lgLcdBitmapHeader->Anonymous_5fa96ca7_9cc3_4b33_b5aa_ccff9833813a
public lgLcdBitmapHeader hdr;
/// BYTE[]
//public fixed byte pixels[NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP)]
public byte[] pixels;
public static int SizeConst { get { return NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP; } }
}
, 나는 모든 웹을 통해보고 그리고 난이 LIB의 그물 포트를 찾았지만 아주 오래된, 그리고하지 않습니다 컬러 비트 맵 (각 색마다 4 바이트)을 사용하지 않고 lgLcdBitmapHeader 구조체 (더 간단한 형식을 사용함)를 사용하지 않기 때문에 문제가 발생했습니다. 또한 소스 코드는 내 것과 매우 비슷합니다.
http://lglcdnet.codeplex.com/SourceControl/changeset/changes/5538
업데이트 1 :
어떤 도움을
유용한 링크를 이해할 수있을 것이다
나는 teory에 따라 일부 진전을했다.
DWORD WINAPI lgLcdUpdateBitmap(IN int device,
IN const lgLcdBitmapHeader *bitmap,
IN DWORD priority);
이 서명은 구조체의 첫 번째 요소에 대한 포인터도 해당 구조체에 대한 포인터이기 때문에 c에 "의미가 있습니다. 사실 lgLcdBitmapQVGAx32에는 lgLcdBitmapHeader 유형의 첫 번째 요소가 있습니다. 즉, lgLcdBitmapHeader는 lgLcdBitmap160x43x1 (첫 번째 요소는 lgLcdBitmapHeader) 또는 lgLcdBitmapQVGAx32 일 수 있기 때문에 C의 가능성을 사용하여 "일반 메서드"를 만들기 위해 모든 것을 모두 캐스팅 할 수 있습니다.
C#에서는이 용량을 에뮬레이트 할 수 없으므로 문제가됩니다. 그래서 lgLcdBitmapHeader에 대한 포인터로 내부적으로 사용되는 lgLcdBitmap160x43x1 및 lgLcdBitmapQVGAx32를 허용하는 "도우미"함수를 만들었습니다.
수행이
은, 그러나, 나에게 또 다른 오류를 주었다System.Runtime.InteropServices.MarshalDirectiveException non è stata gestita
Message=Impossibile effettuare il marshalling di 'parameter #2': Limitazione interna: la struttura è troppo complessa o troppo grande.
Source=G19dotNet
StackTrace:
in G19dotNet.LgLcd.NativeMethods.lgLcdUpdateBitmapQVGAx32(Int32 device, lgLcdBitmapQVGAx32& bitmap, UInt32 priority)
in ConsoleTest2.Program.Main(String[] args) in C:\Documents and Settings\Administrator\documenti\visual studio 2010\Projects\G19dotNet\ConsoleTest2\Program.cs:riga 116
in System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
in System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
in Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
in System.Threading.ThreadHelper.ThreadStart_Context(Object state)
in System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
in System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
in System.Threading.ThreadHelper.ThreadStart()
InnerException:
System.Runtime.InteropServices.MarshalDirectiveException 비 è STATA gestita 메시지 = Impossibile effettuare 위원장 마샬링 디 '매개 변수 # 2'의 영어 버전 : 제한된 내부 구조 : 트렁크와 트렁크를 연결하는 그물. :
System.Runtime.InteropServices.MarshalDirectiveException은 처리되지 메시지 = 불가 '파라미터 # 2'마샬링 수행 내부 제한 : 구조는 그것의 배열을 갖는다
너무 크거나 너무 복잡 307200 바이트, 어떻게해야합니까?
업데이트 2 : http://bytes.com/topic/c-sharp/answers/272048-internal-limitation-structure-too-complex-too-large 그러나 이미지를 : 내 화면에 이미지를 표시하는 관리
, 나는 그것이 작동하는지 "일"의이 유형을 사용했다 나의 teory이 올 것을 의미합니다 보이는 "깨진", 그것은 원래 이미지의 모양을 가지고 있지만 비트 혼란과 무색, 비트 맵을 전달하는 방법에 대한 어쩌면 때문에 의미?
업데이트 3 및 해결 방법 :
내가 나 자신에 의해 문제를 해결이 코드는 정말 못생긴 내가 pastie 내부 여기에 게시거야, 희망 누군가는 유용하게 찾을 수 있습니다.
/// <summary>
/// LONG GetBitmapBits(
/// __in HBITMAP hbmp,
/// __in LONG cbBuffer,
/// __out LPVOID lpvBits
/// );
/// </summary>
/// <param name="hbmp"></param>
/// <param name="cbBuffer"></param>
/// <param name="lpvBits"></param>
/// <returns></returns>
[DllImport("Gdi32", EntryPoint = "GetBitmapBits")]
public extern static long GetBitmapBits([In] IntPtr hbmp,[In] int cbBuffer,[Out] byte[] lpvBits);
[DllImport("Gdi32", EntryPoint = "GdiFlush")]
public extern static void GdiFlush();
public static void FillPixelArray3(Bitmap bmp, ref byte[] array)
{
IntPtr hbmp = bmp.GetHbitmap();
GdiFlush();
//Marshal SizeOf is to "ensure" that other people will notice that array.Length
//must be multiplied
GetBitmapBits(hbmp, array.Length * Marshal.SizeOf(typeof(byte)), array);
}
이 : 당신이 C의 DLL의 소스 코드를 가지고 있기 때문에
IntPtr unhandledPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LgLcd.lgLcdBitmapQVGAx32)));
Marshal.StructureToPtr(bmp, unhandledPtr, true);
res = LgLcd.NativeMethods.lgLcdUpdateBitmap(openContext.device, unhandledPtr, LgLcd.NativeConstants.LGLCD_SYNC_UPDATE(LgLcd.NativeConstants.LGLCD_PRIORITY_NORMAL));
Marshal.FreeHGlobal(unhandledPtr);
어쩌면 당신이 그것을 통과하기 전에 유엔 관리되는 형식들로 뭔가를 마샬링해야? – Machinarius
물론이 방법으로 마샬링하는 방법을 모르겠다. Interop 서비스가 좋지 않다. 나는 화를 내겠다. –
잘 모르겠지만 http : // msdn을 살펴볼 수있다. .microsoft.com/en/US/ 라이브러리/23acw07k.aspx –