質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

5247閲覧

64bitでコンパイルするとMarshalクラスのAllocHGlobalメソッドでエラーが発生

shiode

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/10/12 04:54

現在、C#でシステムを作っています。
自作の印刷プレビュー画面にて、印刷ボタン、余白設定、レポート設定ボタンを配置し、
其々のボタンを押下した際の情報を保持し、印刷時に反映させるようになっています。

開発、実行OS:Windows10 64bit
開発ツール:VisualStudio2017
フレームワーク:4.6.2
ビルドの際、プラットフォームは、64bitを使用

プリンタ情報を読み込む為のロジックにて、★印の部分でエラーが発生します。

/// <summary>
/// プリンター情報を読み込む
/// </summary>
/// <param name="doc">ドキュメント</param>
/// <returns>ポインタ</returns>
private IntPtr mintLoadPrinterSetting(Document doc)
{
IntPtr devPtr;

// 設定ファイル名 string wstrFileName = Path.Combine(Application.StartupPath, mstrPrtSetNmReplace(doc.Printer.PrinterSettings.PrinterName) + ".prt"); // ファイルが存在する場合 if (File.Exists(wstrFileName)) { using (FileStream fs = new FileStream( wstrFileName, FileMode.Open, FileAccess.Read)) { // 読み込み byte[] setting = new byte[fs.Length]; fs.Read(setting, 0, (int)fs.Length); // グローバル領域にメモリー確保 devPtr = Marshal.AllocHGlobal(setting.Length); // 設定コピー Marshal.Copy(setting, 0, devPtr, setting.Length); // ファイルクローズ fs.Close(); } } else { devPtr = Marshal.AllocHGlobal(doc.Printer.PrinterSettings.GetHdevmode()); ★ } return devPtr;

}

エラーメッセージ:

プログラムの実行を続行するための十分なメモリがありませんでした。

試したこと:

ビルドの際、プラットフォームを、32bitを使用したところ、エラーは発生しませんでした。

デバック時に doc.Printer.PrinterSettings.GetHdevmode() の内容を確認したところ、

64bit実行時:0x000001d532fe02d8
32bit実行時:0x13893020

でした。

実行環境のメモリ使用量は、32bit実行時も、64bit実行時も変わらず、
めいっぱい使っているようには見受けられません。(実行環境は、メモリ8GB搭載)

32bitと64bitでポインタの扱いが違うといった情報は
いろいろと出てくるのですが、対処方法が分かりません。

エラーの原因、対処法について、教えて頂きたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ざーっと調べた限りAllocHGlobalは誤りでpinvoke使ってGlobalLockしないといけないようです。

投稿2018/10/12 08:56

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiode

2018/10/17 04:30

回答頂き、ありがとうございます。 私が、pinvokeやGlobalLockが何か、 どのように使うのかが分からないので、 2つの内容を調べて、確認してみます。
guest

0

ベストアンサー

64bit実行時:0x000001d532fe02d8

2Tを超える領域を確保しようとしてますが、それはムリということなんでしょうね

doc.Printer.PrinterSettings.GetHdevmode() という関数が何を返すのか、調べてみてはどうでしょうか

投稿2018/10/12 05:03

編集2018/10/12 05:13
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiode

2018/10/12 07:49

doc.Printer.PrinterSettings.GetHdevmode() について調べてみました。 プリンタ設定に対応する DEVMODE 構造体を識別するハンドルを返す関数でした。 メモリ領域を確保する関数であるMarshal.AllocHGlobal()に引数として渡していることに問題があると判断しました。 ソースを修正し、正しい値でメモリ領域を確保しようと思います。 アドバイスを頂き、ありがとうございました。 大変参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問