2016-06-20 21 views
1

私のアプリケーションはos.Argsからポインターを受け入れます。例えばポインターgolangから文字列

pointer := os.Args[1] //"0x7ffc47e43200" 

は、どのように私はそのポインタを使用し、その場所に保存されている値を得ることができますか?

+3

そのアドレスが有効であるかどうかをどのように知ることができますか?あなたはそのデータで何をするつもりですか? – zmb

+0

@zmbもう1つのアプリケーションがメモリアドレスを使ってこのアプリケーションを呼び出します(実行しません)。 – Joost

+2

しかし、最近のオペレーティングシステムでは仮想メモリを使用しているため、他のアプリケーションはGoアプリケーションと仮想アドレス空間を共有しません。 – zmb

答えて

5

免責事項:これは危険であり、本番アプリケーションでこれを実行する場合は、本当に良い理由があることをお勧めします。それは言っている...

あなたはいくつかをする必要があります。コードは次のとおりです。

package main 

import (
    "fmt" 
    "os" 
    "strconv" 
    "unsafe" 
) 

func main() { 
    str := "7ffc47e43200" // strconv.ParseUint doesn't like a "0x" prefix 
    u, err := strconv.ParseUint(str, 16, 64) 
    if err != nil { 
     fmt.Fprintln(os.Stderr, "could not parse pointer:", err) 
     os.Exit(1) 
    } 

    ptr := unsafe.Pointer(uintptr(u)) // generic pointer (like void* in C) 
    intptr := (*int)(ptr)    // typed pointer to int 
    fmt.Println(*intptr) 
} 

これはGo Playgroundで実行できます。

まず、文字列を数値として解析する必要があります。あなたの例では、16進数を与えたので、16進数で解析します(これはstrconv.ParseUintの "16"の引数です)。 strconv.ParseUintは "0x"プレフィックスを好まないので、私はそれを削除しました。

次に、数値をポインタ型に変換する必要があります。このため、Goコンパイラに特化したunsafe.Pointerタイプを使用します。通常、コンパイラはポインタ型間での変換を許可しません。

  • 任意のタイプのポインタ値をポインタに変換することができる:例外がunsafe.Pointer documentationによれば、ということです。
  • ポインタは、任意の型のポインタ値に変換できます。
  • uintptrはポインタに変換できます。
  • ポインタはuintptrに変換できます。

このように、ポインタに変換するために、我々は最初のunsafe.Pointerに、その後uintptrに変換し、する必要があります。ここから、必要なポインタ型に変換できます。この例ではintポインタに変換しますが、他のポインタ型も選択できます。次に、ポインタを逆参照します(この場合はパニックになります)。

関連する問題