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

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

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

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

Q&A

2回答

1048閲覧

C# *ポインタがのenumにアドレスのenumが設定できない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2022/07/22 12:03

編集2022/07/25 00:16

提示コードの//ここで例外部の行で以下のエラーが発生するのですがこれは何が原因なのでしょうか?同じ状況を再現した実験コードを書きましたが問題なくコンパイルできます。

参考サイト: https://ufcpp.net/study/csharp/sp_unsafe.html#abst

Error
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
実験コード

cs

1using System; 2 3public class Program 4{ 5 enum Status 6 { 7 AAA, 8 BBB 9 10 } 11 12 public static void Main() 13 { 14 unsafe 15 { 16 Status status; 17 18 Status* t; 19 t = &status; 20 21 22 } 23 } 24} 25
問題のソースコード

cs

1using FFmpeg.AutoGen; 2 3internal unsafe class Program 4{ 5 static int Main(string[] args) 6 { 7 AVFrame* frame; 8 AVPacket* pkt; 9 int i, j, k, ret; 10 short* samples; 11 float t, tincr; 12 13 if (args.Length <= 0) 14 { 15 string executable = Environment.GetCommandLineArgs()[0]; 16 //Console.Error.WriteLine($"Usage: {executable} <output file>"); 17 //return 0; 18 } 19 20 var filename = "input.flac"; 21 22 /* find the MP2 encoder */ 23 AVCodec* codec = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_MPEG4); 24 if (codec == null) 25 { 26 Console.WriteLine("Codec not found"); 27 return 1; 28 } 29 30 AVCodecContext* c = ffmpeg.avcodec_alloc_context3(codec); 31 if (c == null) 32 { 33 Console.Error.WriteLine("Could not allocate audio codec context"); 34 return 1; 35 } 36 37 /* put sample parameters */ 38 c->bit_rate = 64000; 39 40 /* check that the encoder supports s16 pcm input */ 41 c->sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S16; 42/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 43 AVSampleFormat av;//列挙型 44 av = AVSampleFormat.AV_SAMPLE_FMT_S16; 45 46 //codec->sample_fmtsはAVSampleFormat型 47 codec->sample_fmts = &av; //ここで例外 48/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 49 *codec->sample_fmts = AVSampleFormat.AV_SAMPLE_FMT_S16; 50 if (!check_sample_fmt(codec, c->sample_fmt)) 51 { 52 string sampleFormat = ffmpeg.av_get_sample_fmt_name(c->sample_fmt); 53 Console.Error.WriteLine($"Encoder does not support sample format {sampleFormat}"); 54 return 1; 55 } 56 57 /* select other audio parameters supported by the encoder */ 58 c->sample_rate = select_sample_rate(codec); 59 c->channel_layout = select_channel_layout(codec); 60 c->channels = ffmpeg.av_get_channel_layout_nb_channels(c->channel_layout); 61 62 /* open it */ 63 if (ffmpeg.avcodec_open2(c, codec, null) < 0) 64 { 65 Console.Error.WriteLine($"Could not open codec"); 66 return 1; 67 } 68 69 using BinaryWriter output = new BinaryWriter(new FileStream(filename, FileMode.Create)); 70 71 /* packet for holding encoded output */ 72 pkt = ffmpeg.av_packet_alloc(); 73 if (pkt == null) 74 { 75 Console.Error.WriteLine($"could not allocate the packet"); 76 return 1; 77 } 78 79 /* frame containing input raw audio */ 80 frame = ffmpeg.av_frame_alloc(); 81 if (frame == null) 82 { 83 Console.Error.WriteLine($"Could not allocate audio frame"); 84 return 1; 85 } 86 87 frame->nb_samples = c->frame_size; 88 frame->format = (int)c->sample_fmt; 89 frame->channel_layout = c->channel_layout; 90 91 /* allocate the data buffers */ 92 ret = ffmpeg.av_frame_get_buffer(frame, 0); 93 if (ret < 0) 94 { 95 Console.Error.WriteLine($"Could not allocate audio data buffers"); 96 return 1; 97 } 98 99 /* encode a single tone sound */ 100 t = 0.0f; 101 tincr = (float)(2 * Math.PI * 440.0 / c->sample_rate); 102 for (i = 0; i < 200; i++) 103 { 104 /* make sure the frame is writable -- makes a copy if the encoder 105 * kept a reference internally */ 106 ret = ffmpeg.av_frame_make_writable(frame); 107 if (ret < 0) 108 return 1; 109 samples = (short*)frame->data[0]; 110 111 for (j = 0; j < c->frame_size; j++) 112 { 113 samples[2 * j] = (short)(Math.Sin(t) * 10000); 114 115 for (k = 1; k < c->channels; k++) 116 samples[2 * j + k] = samples[2 * j]; 117 t += tincr; 118 } 119 encode(c, frame, pkt, output); 120 } 121 122 /* flush the encoder */ 123 encode(c, null, pkt, output); 124 125 ffmpeg.av_frame_free(&frame); 126 ffmpeg.av_packet_free(&pkt); 127 ffmpeg.avcodec_free_context(&c); 128 129 return 0; 130 } 131 132 static void encode(AVCodecContext* ctx, AVFrame* frame, AVPacket* pkt, BinaryWriter output) 133 { 134 int ret; 135 136 /* send the frame for encoding */ 137 ret = ffmpeg.avcodec_send_frame(ctx, frame); 138 if (ret < 0) 139 { 140 Console.Error.WriteLine($"Error sending the frame to the encoder"); 141 Environment.Exit(1); 142 } 143 144 /* read all the available output packets (in general there may be any 145 * number of them */ 146 while (ret >= 0) 147 { 148 ret = ffmpeg.avcodec_receive_packet(ctx, pkt); 149 if (ret == ffmpeg.AVERROR(ffmpeg.EAGAIN) || ret == ffmpeg.AVERROR_EOF) 150 return; 151 else if (ret < 0) 152 { 153 Console.Error.WriteLine($"Error encoding audio frame"); 154 Environment.Exit(1); 155 } 156 157 output.Write(new ReadOnlySpan<byte>(pkt->data, pkt->size)); 158 ffmpeg.av_packet_unref(pkt); 159 } 160 } 161 162 /* check that a given sample format is supported by the encoder */ 163 static bool check_sample_fmt(AVCodec* codec, AVSampleFormat sample_fmt) 164 { 165 AVSampleFormat* p = codec->sample_fmts; 166 167 while (*p != AVSampleFormat.AV_SAMPLE_FMT_NONE) 168 { 169 if (*p == sample_fmt) 170 return true; 171 p++; 172 } 173 return false; 174 } 175 176 /* just pick the highest supported samplerate */ 177 static int select_sample_rate(AVCodec* codec) 178 { 179 int best_samplerate = 0; 180 181 if (codec->supported_samplerates == null) 182 return 44100; 183 184 int* p = codec->supported_samplerates; 185 while (*p != 0) 186 { 187 if (best_samplerate != 0 || Math.Abs(44100 - *p) < Math.Abs(44100 - best_samplerate)) 188 best_samplerate = *p; 189 p++; 190 } 191 return best_samplerate; 192 } 193 194 /* select layout with the highest channel count */ 195 static ulong select_channel_layout(AVCodec* codec) 196 { 197 ulong* p; 198 ulong best_ch_layout = 0; 199 int best_nb_channels = 0; 200 201 if (codec->channel_layouts == null) 202 return ffmpeg.AV_CH_LAYOUT_STEREO; 203 204 p = codec->channel_layouts; 205 while (*p != 0) 206 { 207 int nb_channels = ffmpeg.av_get_channel_layout_nb_channels(*p); 208 209 if (nb_channels > best_nb_channels) 210 { 211 best_ch_layout = *p; 212 best_nb_channels = nb_channels; 213 } 214 p++; 215 } 216 217 return best_ch_layout; 218 } 219}

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

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

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

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

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

guest

回答2

0

例外の内容にもよりますが、オブジェクトのフィールドとして定義されるenum型の変数は、定義元の型とアクセスレベルが統一されている必要があります
実験コードでは変数がメソッド内で宣言されているため、定義元のアクセスレベルに関係なくコンパイルスルーが有効となります

なお、該当のフィールドは配列ポインタである可能性が考えられます
https://ffmpeg.org/doxygen/1.0/adpcmenc_8c-source.html#l00706(721行目以下)

投稿2022/07/26 20:42

Manabu

総合スコア25

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

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

Manabu

2022/07/26 20:52

リクエストエラーで回答が複数回投稿されてしまったため削除依頼を申請しました ご迷惑おかけして申し訳ありません
退会済みユーザー

退会済みユーザー

2022/07/27 01:18

なるほどつまり問題のソースコードはアクセスレベルが違うためコンパイルエラーになるということでしょうか?
guest

0

AVSampleFormat.AV_SAMPLE_FMT_S16はただのenumの値なのに
その値をポインタのアドレス扱いにしてそのアドレスにアクセスしようとしてるから
そのアドレスにデータがあるわけがないのでアクセスさせませんよって言われてるのでは?

投稿2022/07/22 14:39

RiaFeed

総合スコア2701

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

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

退会済みユーザー

退会済みユーザー

2022/07/23 05:01 編集

codec->sample_fmtsはunsafeによるポインタなのですがなぜでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問