none
libをstdcallで作成するには RRS feed

  • 質問

  • こんにちは。

    dllが相互依存関係におちいったため、libだけ作成しようと

    コマンドラインから

    lib.exe /def:xxxx.def /out:xxx.lib

    とうってlibファイルを作成しました。

    ところがここで作成したlibを参照するとリンクエラーを起こすので調べてみたところ、

    どうやらstdcallで関数を呼びたいのに、libに定義された関数がstdcallで作成されていないたというのが原因であることまでわかってきました。

    stdcallで作成されていないと判断した理由としては、

    作成したlibファイルを開いてみてみると、関数名の後ろに@が見当たらなかったためです。

    ここで質問ですが、

    上のlib.exeでlibを作成して、stdcall形式に対応するためには、どうしたら良いでしょうか?

    ご存知の方がいらっしゃいましたら、ご教示頂けませんでしょうか。

    よろしくお願いします。

     


    2011年5月25日 6:38

回答

  • __stdcall __cdecl 等は「呼び出し規約」の定義で、コンパイラが
    *.objを作成するときに決定されます。両者は関数の修飾名が異なる
    だけでなく、引数のためのスタックの扱いが異なるので修飾名を一致させた
    だけではその関数を利用できません。

    従って、ご希望の結果を得るためには
    1.Exportされた__cdecl関数を呼び出す、__stdcall関数を作成し
     (つまりラップし)それをExportする。
    方法が考えられます。

    しかし、「DLLが互いに依存しあう」という状況とは、単に
    2.分離する部分が間違っていた
    だけなので、分離する部分を検討しなおせばよいだけの気がします。

    以上いずれの場合においても、
    3.コードの修正が必要
    4.であれば当然、分離する部分も変更したほうが良い
    ことになると思われます。

    呼び出し規約が未定義な関数をど~するか、のオプションが、/Gd /Gz等
    コンパイラオプションで指定できます。

    • 回答としてマーク birdland007s 2011年5月26日 12:38
    2011年5月26日 1:57

すべての返信

  • __stdcall __cdecl 等は「呼び出し規約」の定義で、コンパイラが
    *.objを作成するときに決定されます。両者は関数の修飾名が異なる
    だけでなく、引数のためのスタックの扱いが異なるので修飾名を一致させた
    だけではその関数を利用できません。

    従って、ご希望の結果を得るためには
    1.Exportされた__cdecl関数を呼び出す、__stdcall関数を作成し
     (つまりラップし)それをExportする。
    方法が考えられます。

    しかし、「DLLが互いに依存しあう」という状況とは、単に
    2.分離する部分が間違っていた
    だけなので、分離する部分を検討しなおせばよいだけの気がします。

    以上いずれの場合においても、
    3.コードの修正が必要
    4.であれば当然、分離する部分も変更したほうが良い
    ことになると思われます。

    呼び出し規約が未定義な関数をど~するか、のオプションが、/Gd /Gz等
    コンパイラオプションで指定できます。

    • 回答としてマーク birdland007s 2011年5月26日 12:38
    2011年5月26日 1:57
  • .def ファイルの EXPORTS のところに、しかるべき命名規約で関数を記述すればいいのではないでしょうか。
    命名規約は次のスレッドあたりをご参考に。

     DLLからのエクスポート関数
     http://social.msdn.microsoft.com/Forums/ja-JP/vcgeneralja/thread/e6f937db-e496-461a-b206-29ddab40af93
    2011年5月26日 2:02
  •  

    ご返信ありがとうございます。

    objはExportされた関数が_stdcallか_cdeclかの情報を持っていると思い、

    コンパイルで作成したobjを入力にlib.exeでlibをつくってみました。

    そうすればstdcallでExprotされたlibが作れると仮定してのことです。

    ところが、ここで作られるlibはどうも容量が大きいので、スタティックリンク用のlibになってしまっている感じがします。

    この私の認識が正しければの話ですが、なんらかの方法でobjからダイナミックリンク用のlibを作成することはできるのでしょうか?

     

      


    2011年5月26日 3:55
  • *.obj内の関数が__stdcallが__cdeclかは、修飾名で判断するしかないと思います。
    従って「事実と異なる嘘の修飾名に改名し公開」することは正しい解決方法では
    ありません。

    HELPに「LIBの概要」がありますので、それを参照しましょう。
    Lib.exeを使用して特定*.obj内の特定関数のエクスポートを指定するには
    LIBのコマンドラインで
     1./EXPORT:entryname・・・・・ オプションを指定する。
    の方法があります。
    残念ながら、詳しく説明できるほど、このオプションを駆使したことはありません(vv;)。
     2.*objファイル、ライブラリファイル名に__declspec(dllexport)を指定する
    は、まったくやったことがありませんが、HELPから丸写ししました。あしからず
     3.指定する*.defファイル内のEXPORT欄に記述する。
    も、できるはずです。
    しかし、当初の問題の解決方法とは関係ない可能性が高いですね。

    2011年5月26日 5:08