2016-09-16 12 views
0

그래서 dll 파일에서 이미지 리소스를로드하려고합니다. 이를 위해 나는 핸들과 자원 ID를 부여하는 방법 DLL에서 이미지 리소스를로드 LoadImage에서 반환 한 핸들에서 Image.FromHBitmap을 호출 할 때 GDI + 오류가 발생했습니다.

static Bitmap GetImageResource(IntPtr handle, string resourceId) 
{ 
    IntPtr img_ptr = NativeMethods.LoadImage(handle, "#" + resourceId, IMAGE_ICON, 16, 16, 0); 

    if (img_ptr == IntPtr.Zero) 
     throw new System.ComponentModel.Win32Exception((int)NativeMethods.GetLastError()); 

    return Image.FromHbitmap(img_ptr); 
} 

을 만들었습니다. this question I asked yesterday에 따르면 나는 이드에게 #을 앞에 붙여야한다. 이제 LoadImage에 의해 반환 된 핸들은 내가 사용이 핸들에서 비트 맵 이미지를 만들려고하지만 때, 더 이상 0이 아닌 Image.FromHbitmap 나는 System.Runtime.InteropServices.ExternalException는 일반 오류가 GDI에서 발생 +

(또는

말을 얻을 유사한 내용, 나는 영어로 메시지를받지 못한다. 그래서 나는 대략 번역했다.)

나는 이미 thisthis 질문을 읽었지만 그들은 나를 도와주지 않았다.

왜 이런가요? 사전 DLL이 .NET 어셈블리 인 경우

+0

이미지가 아니라 아이콘을로드하는 것은 완전히 정상입니다. 대신 Icon.FromHandle()을 사용하십시오. 아이콘 객체를 다시 사용할 수 없다는 확신이들 때 DestroyIcon으로 아이콘을 다시 파괴해야합니다. –

답변

0

감사, 당신과 같이, Assembly.GetManifestResourceStream를 호출 할 수

public static Bitmap getBitmapFromAssemblyPath(string assemblyPath, string resourceId) { 
    Assembly assemb = Assembly.LoadFrom(assemblyPath); 
    Stream stream = assemb.GetManifestResourceStream(resourceId); 
    Bitmap bmp = new Bitmap(stream); 
    return bmp; 
} 

를 네이티브 DLL (안 어셈블리) 인 경우, 대신 상호 운용성을 사용해야합니다 . 다음과 같이 솔루션 here이 있고, 요약 될 수있다 :

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags); 

[DllImport("kernel32.dll")] 
static extern IntPtr FindResource(IntPtr hModule, int lpID, string lpType); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo); 

[DllImport("kernel32.dll", SetLastError=true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool FreeLibrary(IntPtr hModule); 

static const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002; 

public static Bitmap getImageFromNativeDll(string dllPath, string resourceName, int resourceId) { 
    Bitmap bmp = null; 
    IntPtr dllHandle = LoadLibraryEx(dllPath, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE); 
    IntPtr resourceHandle = FindResource(dllHandle, resourceId, resourceName); 
    uint resourceSize = SizeofResource(dllHandle, resourceHandle); 
    IntPtr resourceUnmanagedBytesPtr = LoadResource(dllHandle, resourceHandle); 

    byte[] resourceManagedBytes = new byte[resourceSize]; 
    Marshal.Copy(resourceUnmanagedBytesPtr, resourceManagedBytes, 0, (int)resourceSize); 
    using (MemoryStream m = new MemoryStream(resourceManagedBytes)) { 
     bmp = (Bitmap)Bitmap.FromStream(m); 
    } 

    FreeLibrary(dllHandle); 

    return bmp; 
} 

없음 오류 처리를 첨가하지 않은,이 하지 생산 준비 코드입니다.

주 : 아이콘이 필요한 경우, 당신은 스트림을 수신 아이콘 생성자 사용할 수 있습니다

using (MemoryStream m = new MemoryStream(resourceManagedBytes)) { 
     bmp = (Icon)new Icon(m); 
    } 

을 그리고 그에 따라 반환 형식을 변경해야합니다.

+0

정확히'bptr'이란 무엇입니까? –

+1

오타. 적절한 변수 이름으로 코드를 변경했습니다. –

+0

리소스 ID 만 가지고 있는데,'resourceName' 매개 변수에는 무엇을 사용해야합니까? –