C言語なら俺に聞け 142 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
歯痛制御のバグ
珍しくない
発見しづらく、再現性も乏しく、解析に手間がかかりがち
レベルの低い開発者が混ざると大変 マルチスレッドは、たまたま動いているだけで、
ちょっとしたタイミングで、バグる
初心者は、たいてい、コンパイラのバグのせいにする。
それか、リリースビルドの最適化がおかしいと言う
プロは、Elixir などの関数型を使う いや、ちゃんとロックすりゃなんとかなるってw
もちろん最初から考慮されてる言語は何も考える必要ないからうまく行って当然。 初心者です。エラーでまくりでコンパイルすら出来ません。アドバイスお願いします。
■やりたいこと。
マウス入力にrawinputを用いるアプリのWndProcをフックし、rawinput(WM_INPUT)を強制オフにし、DirectInputを使用するように指定。
↓ソース
// FuckRawInput.c
#include <windows.h>
LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE:
{
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = 0x01;
Rid[0].usUsage = 0x02;
Rid[0].dwFlags = RIDEV_NOLEGACY;
Rid[0].hwndTarget = hWnd;
RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) ;
break;
}
-----
また、この方法が最適なのかも不明です。ほかの方法等もあったら教えてください >>414
そのままの意味でC言語初心者ですけど?
rawinputを消し去りたいがためにプログラム未経験ながらC言語入門書を読み、
Visual studio2013でハローワールドのコンパイルに成功した所です。
他スレで聞いたら、
DLLインジェクションでAPI関数を置き換えといわれたんですが、
まぁ、それと同じような事をしようとして書いたソースが>>412
目的達成するためにどこが悪いのか教えてくださいよ どうやってWndProcをフックするつもりなのか知らんが、初心者のやることじゃない >>412
とりあえず文法エラーのないソースを出せよ >>415
windowsプログラムでFuckファックは初心者がやるものではない
何故かと言うとFuckファックは非常に拙いからで、これはご存じの通りにFuckファックつまりはセクロスとかセックスを意味する
FuckRawInputなどと書かれると非常に面食らうので、動作には全く関係ないがFuckファックの箇所をHookフックとする
Fookという間違いならまだしもFuckが出てくるのは途轍もなく拙い
windowsプログラムは入門書を一通り終えた後にようやく手を出せる程度に面倒くさい C++の標準でWindowsのCOMみたいなのはできるの?
モジュールがあれば動的リンクできて、向こう側の関数の形式とエントリポイントがわかるような。 >>418-422
WndProcフックでは目的の動作できなくて、APIフックしか手がないと分かりましたので、
MSのdetourとかいうの使ったAPIフックに変更されました。改めて、見てください。
@やりたいこと
Rawinputマウス関数が呼び出させられる代わりDirectInputマウス関数を呼び出し、強制的にマウス操作をDirectInputにする
ソース↓
// APIhook_RawInput.c
#include <windows.h>
#include "detours.h"
hoge target = NULL; // ターゲットポインタ
hoge tp = NULL; //トランポリンポインタ
// 関数生成
BOOL WINAPI Direct_Input(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
return tp(hWnd, Msg, wParam, lParam);
}
// user32インスタンス
HINSTANCE xxxxx;
case WM_CREATE:
//user32.DLLをロード
xxxxx = LoadLibrary("user32.dll");
//Raw Inputポインタ取得
target = (hoge) GetProcAddress(xxxxx, "WM_INPUT");
// WM_INPUTフック、"WM_INPUT"→"Direct_Input"置き換え
tp = (hoge) DetourFunction((PBYTE) target, (PBYTE) Direct_Input);
break;
// 終了時の処理
case WM_DESTROY:
// フック削除
DetourRemove((PBYTE) tp, (PBYTE) Direct_Input); >>426
で、お前が聞きたいのは「C言語」に関するどんな質問なんだ? 会話にすらなってないな。
こういうのホントにいるんだよなあ。、。 >>415
> どこが悪いのか教えてくださいよ
頭と態度。
APIスレも見たけど、君には無理。 これ無理だろうWindowsプログラムの言語を理解してないと直せないっしょ 勘所がすぐつかめる人ならそうでもない
知らんOS知らん言語知らん環境でもデバッグできちゃうんだぜ
あいつら宇宙人だろ >16 :デフォルトの名無しさん:2006/03/10(金) 22:15:19
>>>10
>> こんな変数名があちこちに散らばっているのがPerl
>
>大学の研究室のボスは、特殊変数の表をふ〜んと2分ほど眺めて完全に暗記した。
>
>そういうレベルの人たちのための言語なんだなと思って、トイレで血の涙を流した。 お助けください。
自作コードにおいて、以下の部分でmemsetの際にsegmentation faultになってしまいます。
int n = 2;
char charList[n+1][32]; // 32文字の文字列をn+1確保・・・@
func(charList); // charListに書き込む関数
for (int i = 0; i < n; ++i) memset(charList[i], ' ', 32); // 空白で埋めたい
funcを省いたりmemsetの前に適当にcharListをプリントしたりすると何故か問題なく動きます。
この部分だけ切り出したテストコードでは全く再現しませんでした。
この手のエラーでよくあるのは未初期化領域へのアクセスだと思いますが、
@で領域の確保はできているからこれは原因ではないですよね?
どこがエラーの原因でしょうか・・・? 配列サイズ 32要素で 32個 空白で生めてるが
文字列 という用語を使ってるあたり func は一般の文字列操作してそうだけど
終端記号 '\0' の分の考慮が落ちてるんでないの? 「文字列」で32文字を取り扱いたいのなら 33要素の器が必要ってことで
文字の配列なら問題ないけどねー >>437
>char charList[10000][10000]; // 32文字の文字列をn+1確保・・・@
くらい確保して実行すれば動くだろ int n = 2;
char charList[n+1][32];
C言語的に、これってOKだっけ? char charList[n+1,32]こうしないとダメだよね?なにかっこ二つ使ってんだよ読み込めねえよって昔2次元配列で怒られたな 最近どころか、20年近く前からだし
>>448みたいな文法は存在しないんだけど、どこの世界のC言語なんだろ iOS11にしたらまともに入力できない
このクソOS iOS11にしたらまともに入力できない
このクソOS 返事が遅れてすみません。レスありがとうございます。
再現性の乏しい質問で申し訳ないです。
>>438
nは変わらないです。
>>441
文字列操作ではあるんですが終端記号は書き込みません(全部文字だけ)
>>444
OSはCentOS 6.9、言語はc++、コンパイラはgcc7.1.0です。
さっぱり原因が想像できないのですが、考えられる可能性としては、funcの中でメモリがずたずたに壊れたものの
偶然エラーにならずに戻ってきてmemsetでやっと死んだ、というパターンでしょうか? >>452
存在するだろ
char charList[32]と等価になるぞ 二次元配列の宣言についての話で合って
コンパイルが通るかどうかだけの話なんてしてねーぞ ってか二次元配列と二重配列間違ってねーか?
それとfunc呼んでからmemsetしたらfunc呼ぶ意味あるの?
memsetもループさせるんじゃなく一回で全部fillした方がよくない?
とかとか。 >>467
1行目 イミフ
2行目 意味があるから呼んでるんだろ
3行目 明確な利点があるならそれを書け >>468
ポインタの配列と二次元配列を間違ってるのではないかってこと。
書き込んだあと空白で埋めたら意味なくないか?funcが何してるか知らんけど >>469
funcの中身を知らないのに「意味無い」とか「意味あるの?」とかっていう書き込み、意味あるの?
それを聞けば問題の解決になるの?
少なくとも空白を埋めてない部分があるし
問題が発生する範囲で簡略化したのかもしれないし
当然意味があるから呼んでるんだろうと思うのが普通 最近オブジェクト指向が入り口で、C言語がわからんっていう子が多いからなあ 再現する最小限のコードに削ってるうちに問題点を自ら発見して終了 つーかfunc()以外の部分で特に問題が見当たらないならfunc()のせいで確定という単純明快な話
自作コードならfunc()もうpできるっしょ >>470
出されたソースのコメント見ると、配列の考え方が間違ってるように感じるけどね。それを示唆したかっただけだよ。 >>462
ふと疑問に思ったんだが、
>func(charList); // charListに書き込む関数
関数を呼び出す際に、nの値を教えなくて良いのか? >>475
例外とは関係ない
合コンじゃないんだから無駄に話を広げる必要はない
問題の解決が遅くなるだけ あとはfuncの中身を見ないとなんとも
組み込みのショボい環境だとスタックオーバーフローって可能性も無いことは無いが struct I2C_MEM //構造体の型宣言
{
char DEV_ADR ;
char REG_ADR ;
char DATA[0x03] ;
};
struct I2C_MEM I2C_MEM[3] =//構造体の型宣言
{
{ 0x7C , 0x01 , 0x00000000 }
{ 0x7C , 0x01 , 0x00000000 }
{ 0x7C , 0x01 , 0x00000000 }
} ; ↑構造体の初期化で
charを連続4byte設定するときの書き方
0x00000000はたぶん違いますよね?
どう書けば良いんですか?
初心者過ぎてすいません struct I2C_MEM //構造体の型宣言
{
char DEV_ADR ;
char REG_ADR ;
char DATA[0x03] ;
};
struct I2C_MEM I2C_MEM[3] = //構造体の初期化
{
{ 0x7C , 0x01 , 0x00000000 }
{ 0x7C , 0x02 , 0x00000000 }
{ 0x7C , 0x03 , 0x00000000 }
} ; >>479
> struct I2C_MEM
> {
> char DEV_ADR ;
> char REG_ADR ;
> char DATA[0x03] ;
> };
struct I2C_MEM I2C_MEM[3] =
{
{ 0x7C , 0x01 , {0} }
{ 0x7C , 0x01 , {0} }
{ 0x7C , 0x01 , {0} }
} ; >>482
回答ありがとうございます!
ちなみにこれだったらどうかくんでしょうか?
struct I2C_MEM I2C_MEM[3] = //構造体の初期化
{
{ 0x7C , 0x01 , 0x12345678 },
{ 0x7C , 0x02 , 0x12345678 },
{ 0x7C , 0x03 , 0x12345678 },
} ; >>483
struct I2C_MEM I2C_MEM[3] =
{
#ifdef BIG_ENDIAN //ビッグエンディアンの場合
{ 0x7C , 0x01 , {0x12, 0x34, 0x56, 0x78} },
{ 0x7C , 0x02 , {0x12, 0x34, 0x56, 0x78} },
{ 0x7C , 0x03 , {0x12, 0x34, 0x56, 0x78} },
#else // リトルエンディアンの場合
{ 0x7C , 0x01 , {0x78, 0x56, 0x34, 0x12} },
{ 0x7C , 0x02 , {0x78, 0x56, 0x34, 0x12} },
{ 0x7C , 0x03 , {0x78, 0x56, 0x34, 0x12} },
#endif
} ; >>484
> char DATA[0x03] ;
おっと、これじゃあ4バイト入らないぜ。
char DATA[4];
にしないと。 全くどうでもいいことだが最近の若いモンはスマホに合わせて上矢印なのな
一つ勉強になった >>484
#ifdef BIG_ENDIAN
# define ENDIAN_FIX(a,b,c,d) a,b,c,d
#else
# define ENDIAN_FIX(a,b,c,d) d,c,b,a
#endif
struct I2C_MEM I2C_MEM[3] =
{
{ 0x7C , 0x01 , {ENDIAN_FIX(0x12, 0x34, 0x56, 0x78)} },
{ 0x7C , 0x02 , {ENDIAN_FIX(0x12, 0x34, 0x56, 0x78)} },
{ 0x7C , 0x03 , {ENDIAN_FIX(0x12, 0x34, 0x56, 0x78)} },
} ; 構造体の中身から推測すると、
書く順番はエンディアンに依存しないと思う
単純に配列の頭から1バイトずつ送信するだけ
仮にエンディアンで順番が変わるとしても
どうせガッツリ環境依存なコードなんだから
依存しちゃえばいい
環境依存が無いコードを書くつもりなら、
charが1バイトかどうかにも依存しないようにしないとね >>488みたいなマクロは最悪
エンディアンていう言葉を覚えたばっかりの初心者が作る糞コード エンディアンについて解説が必要ですか?
はい/いいえ struct I2C_MEM //構造体の型宣言
struct I2C_MEM I2C_MEM[3] =//構造体の型宣言
この手の文法で自明なことをコメントにする文化はなくならないのかな 俺のコードはその対極
大きな流れしかコメントをかかない I2Cか。データは8ビットで受けて、8ビットシフトしてビットORだな。
data = hi<<16 | mid<<8 | lo >>492
お前の糞マクロ、どの辺が糞か解説が必要? やってみなじゃない。どう動くかじゃなくてどう書くかか。
どうなって欲しいのかが書かれてないから答えられないな。 >>465
全体のコードは自作というか(自社製)ですが、funcは他社のライブラリなんです。
ソースがあればなんとかなったのかもですが・・・。
>>467
実際はfunc呼んだ後にcharListの値を呼んで色々作業しています。
>>469
普通の2次元char配列のつもりです。2次元配列というのはC言語的にはシンタックスシュガーにすぎず、
char a[m][n]もchar a[m*n]も等価なのですよね。なので、先頭ポインタから(m*n-1)個先までの
アドレスの範囲内なら範囲外アクセスエラーは起こり得ないと理解しています。
>>474の結論に至る前に、何かC言語で致命的な勘違いや思い込みをしているのかと
思って質問した次第です。今思うとエスパー回答を強いてしまって大変申し訳ありませんでした。
ひとまずはfuncを一切呼ばない形に直して事なきを得ました。
>>437で言った、「charListをプリントしたりすると何故か問題なく動く」からそれで一時凌ぎする考えも
頭をよぎりましたが、思いとどまりました。
ひとまずこれで終えます。回答くださった方々、本当にありがとうございました。 >>503
×charListの値を呼んで
○charListの内容をstringに変換して(charListは不変) >>503
>char a[m][n]もchar a[m*n]も等価なのですよね
そうだっけ? char[m][n]はchar**、char[m*n]はchar*、データ型は違う ■ このスレッドは過去ログ倉庫に格納されています