1

多くの異なるOSのバイナリを持つプログラムがあります

バイナリの場所を取得する必要があります (自動アップデータを考えてください)

「あなたの」OSでこれを行う方法は?

(一種の挑戦と考えてください:))

編集注:プログラムは移植可能(フラッシュドライブなどで実行)またはインストール可能(たとえば、最初は.deb形式)

EDIT2:ここに私がすでに持っているものがあります:

/**
 * Get the location of the executable
 * @return the location of the executable, as a string.
 */
const char *GetExecutableLocation()
{
   const char *path;
   char buf[1024];

   #if defined (WIN32) || defined (WIN64)
      GetModuleFileName(path, &size);
   #elif defined (__APPLE__)
      _NSGetExecutablePath(path, &size);
   #elif defined(UNIX)
      if (readlink("/proc/self/exe", buf, sizeof(buf)) == -1) path = buf;
   #elif defined(__FreeBSD__)
      int mib[4];
      mib[0] = CTL_KERN;
      mib[1] = KERN_PROC;
      mib[2] = KERN_PROC_PATHNAME;
      mib[3] = -1;
      sysctl(mib, 4, buf, sizeof(buf), NULL, 0);
      path = buf;
   #elif defined(SUNOS)
      path = getexecname();
   #endif
   return path;
}

(私はUNIXセクションのみをテストしたことに注意してください。他については知りません)

4

1 に答える 1

3

ポータブルな方法はありません。

主なオペレーティング システムの大まかなアイデア (ここでは詳細を省きます):

  • Windows: GetModuleFileNameW(nullptr) を呼び出して、実行中のプログラムへのパスを取得します。
  • MacOS: [[NSBundle mainBundle] bundlePath] を使用して、メイン バンドル ディレクトリを取得します (実行可能ファイル自体の呼び出しもありますが、ほとんどの場合、データ ファイルを検索する必要があります)。この部分を Objective-C++ としてコンパイルする必要があります。代わりに CFBundle を使用することを考えていましたが、当時は面倒でした。
  • Linux: 「本当に良い」方法はありません。ほとんどの場合に動作する readlink(/proc/<mypid>/exe) に落ち着きました。プログラムがハード リンクを介して呼び出されると失敗します。

注: argv[0] は一般的に役に立ちません。コンソール環境でプログラムを呼び出すために使用された名前を提供しますが、シェル検索パスを解決せず、一部の環境では使用できない場合があります。Windows GUI プログラムには存在しません。また、GUI 経由でプログラムを実行するときに、MacOS が argv[0] として何を渡すかさえわかりません。

于 2012-09-17T23:51:49.783 に答える