2012-03-31 4 views
0

私は、DellのロックされたBIOSのための "マスタコード"を生成するkeygenのCソースコードを持っています。ポートCのコードをC#に変換します。ポインタのトラブル

多くの読書をして尋ねると、さまざまな結果が得られました。

しかし、冒険と学術目的のために私の目標であるC#コードでそれらを書く方法がわからないことがたくさんあります。

例えば、私は次のようにunsigned char outData[16]がC

にC#では、私はこれを書き直し言う:

byte* outData = stackalloc byte[16]; 

この方法により、C#の上に格納されたバイト値としてRAMに同じサイズでありますその後、私はC#で次の操作を行うことができます(http://bytes.com/topic/c-sharp/answers/658913-unsigned-charに基づいて)C

にunsigned char型:

int* testPointer = (int*) outData; 
*testPointer = 0x67452301; 

これを行うことで、outDataの位置0,1,2,3を変更しました(バイトはC#(8ビットvs 32ビット)のintの4分の1です)。unsigned charと同じリレーションとCのint私は間違っていません)。

byte outDatatestPointer物の上記のすべてのものはCでこの方法によって行うことができる:インデックスが1から始まる(再度

unsigned char outData[16]; 
*(int *)(&outData[0]) = 0x67452301; 

3、2、1位置及びOUTDATA 4が変更されこの場合CではなくC#であるため)。

だから、C#2に移植され、32ビット整数のポインタで、技術的にunsigned char型の変更値を行って、それが技術的に

は今、私はの値を変更したいC.上と同じ結果を与える必要があります32ビットのintポインタを介してC#の関数からoutDataを取得しますが、パラメータとして渡すことはありません。だから、唯一の解決策は、outDataをグローバル変数にすることです。それから、大きな問題が発生します...私はグローバルとしてoutDataを置く場合、それはメソッド内にない場合、クラスまたは構造体に含まれている必要があります(メソッドの変数はグローバルではありません。知っている)。

struct/class(私が知っている限り唯一の方法)を介してグローバルoutDataを行うと、outDataは管理されたデータ型になり、GC(GarbageCollector)のためにそこからRAMに移動し、ポインタoutDataへの大きな問題になります。そこで、ここではRAM上の固定場所に一時的にoutDataを配置するための固定ステートメントが出ますが、固定ステートメントではキャストは許可されず、次に実行できません:int* testPointer = (int*) outData;、outDataには別のブロックがありますtestPointerよりもサイズが大きく、キャストが必要です。

すべての前のものが言った、本当の質問になる。 32ビットのintポインタを使用して、C#の関数からoutDataの値を変更するにはどうすればよいですか? OR ...ポインタを使用してoutData whitoutにこれらの変更を行うにはどのようなアルゴリズムを使用できますか?outDataは安全でないコンテキストを必要としない標準値型になると仮定しますか?

私が達成したい実際の目的はC#へのポートCコードであり、OO(オブジェクト指向)パラダイムを使用するので、第2の質問に対する多くの答えが本当に大好きです。

私はポインタを使ってRAMに格納された値の変更を行い、異なるブロックサイズを使用するアルゴリズムを理解しようと夢中になります。これを行うためのポインタが必要です。 C#および他のオブジェクト指向のプログラミング言語。

回答ありがとう!

また、参考のために、ここで私はポートがしたいプログラムの完全なCコードです:

http://pastebin.com/w8VQjVBu

私は約40%の移植を行ってきたが、それらのC関数がポインタに行く、異なるブロックサイズとそのものは本当に数週間の* * &に苦しんでいる!

+1

C#はCと同じプログラミング言語ではありません。コードの行単位の変換を行うことはできますが、それは良い考えではありません。 「移植」の背後にある全体の考え方は、コードを実際にターゲット言語の慣用コードに変換することです。あなたはC#でポインタを使う必要は全くありません。 –

+0

右あなたは私の要点を理解していましたが、OOパラダイムを使ってこのkeygenを再作成し、すべてのアイデアとアルゴリズムをC#に入れたいと思っています。繰り返しますが、私の本当の答えが欲しいのは、このキージェネをC#に移植する方法です。私が直面している唯一の "but"は、異なるバッファサイズのポインタでCのように変数の値を変更することです。 – mishamosher

+0

オブジェクトの値を変更するだけです。スタックオーバーフローは、実際にあなたにC#を教える場所ではありません。あなたは本当に本を手に入れ、まず言語を学ぶ必要があります。 –

答えて

1

32ビット整数の値をバイト配列の最初の4バイトにコピーしようとしているようです。今

var n = 0xFAFBFCFD; 
var a = new byte[16]; 
var temp = BitConverter.GetBytes(n); 
temp.CopyTo(a, 0); 

:それはBitConverter.GetBytesメソッドを使用し、他のアレイへの結果として得られたバイトをコピー行うに

コメントのいくつかのように

a[0] == 0xFD 
a[1] == 0xFC 
a[2] == 0xFB 
a[3] == 0xFA 

は、それをしようとする悪い考えだと言いますC#をCのように書く。

+0

本当に素晴らしい、素晴らしい方法!さて、もし私が言いたいのは、32ビット符号付き整数をバイト配列に変換せず、yesをmmm ... 128ビット10進数を符号なし16ビット整数の配列に変換することです。私はすでにint、double、float、singleなどのBitConverterがあることを認識しました。int、double、float、singleなどのUInt16Converterのようなものがありますか? – mishamosher

+0

すべてのMSDNの検索コンバータの結果、すべての種類の数値変数と組み合わせに対してコンバーターがあることがわかりましたが、「Convert.To 」メソッドのように機能します。 GetBytesのようなものは見つけられませんでした。もっとたくさんのもの(GetUInt32s、GetSBytesなど)があります。 – mishamosher

+0

GetBytes - > Byte Array - > ToUint16という複数の変換ステップが必要です。BitConverterクラスは、プリミティブをバイト配列との間で変換するためのメソッドを提供します。 –

0

整数で構成された16バイトのチャンクの読み書きについては、BinaryReaderとBinaryWを探していると思いますライタークラス。 Googleでは、これらのクラスの使用方法に関する豊富なデモンストレーションを行います。

+0

Brannonありがとうございます。GetBytes - > Byte Array - > To と同じことをやっていますが、これらの変換を扱うのはもっと面白いことがあります。それがBitConverterではなく、私が保つ理由です。重要なのは、StreamWritersに依存していることに気づくことだけですが、それによって物事が大きくなります。 – mishamosher

関連する問題