0

そこで、dll ファイルから画像リソースを読み込もうとしました。これを行うために、メソッドを作成しました

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);
}

ハンドルとリソース ID を指定して、dll からイメージ リソースをロードします。昨日私が尋ねたこの質問によると、ID の前に # を追加する必要があります。LoadImage によって返されるハンドルはゼロではなくなりましたが、このハンドルから Bitmap イメージを作成しようとする とImage.FromHbitmapSystem.Runtime.InteropServices.ExternalException

GDI+ で一般的なエラーが発生しました

(または同様のもの、英語でメッセージが届かないので、大まかに翻訳しました)

私はすでにこれこの質問を読みましたが、役に立ちませんでした。

どうしてこれなの?前もって感謝します

4

1 に答える 1

0

Dll が .NET アセンブリの場合、次の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 (アセンブリではない) の場合は、代わりに Interop を使用する必要があります。ここに解決策があり、次のように要約できます。

[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;
}

エラー処理は追加されていません。これは本番環境向けのコードではありません。

注: アイコンが必要な場合は、ストリームを受け取る Icon コンストラクターを使用できます。

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

それに応じて戻り値の型を変更する必要があります。

于 2016-09-16T11:43:38.043 に答える