DLLでC++のオーバーロードをするには

解決


ひげ犬  2004-03-15 13:08:03  No: 53312

C++でオーバーロードしたDLL内の関数を暗黙的
リンクでも明示的リンクでも活用したいのですが、
装飾名のためかあんまりうまくいきません。

理想的な方法としては、暗黙的リンクの場合は
普通に実引数を与え関数を呼び出せば、目的の
関数が実行される。
明示的リンクの場合は、GetProcAddressに与える
関数名が"DllFunc(int)"のように、引数の型から
簡単に連想できる。…といったものです。
どちらか一方だけならなんとかなるんですが…。
(DLL内だからといって、関数名に括弧を使って
いいのかどうかも謎です…。)

そもそも、このような事ができるかも…と思って
しまったのはDUMPBIN /EXPORTSコマンドで.libと
.dllファイルを覗いていたら、エクスポートした
関数が.libは装飾名で.dllは.defで指定していた
エントリー名で書かれていたからです。

これは暗黙的リンクでは装飾名で探して、明示的
リンクでは単純な名前で探せるようするためだと
思うのですが、

これを応用して.defファイルのEXPORTS文で内部名を
こんな風に
DllFunc(void)=?DllFunc@YGHXZ
DllFunc(int)=?DllFunc@YGHH@Z
装飾名で指定すれば…
と考えたのですが、この場合何故だか.libファイル中の
関数名までもエントリー名そのまんまのDllFunc(void)に
なってしまいました。そのため.libにその装飾名がない
せいか、暗黙的リンクではビルド時にDllFunc(void)は
未解決です!というエラーが出てしまいました。

他にも色々と.defファイルで実験してみたんですが、
・内部名に装飾名を指定すると、
  .libも.dllもエントリー名になる。
・内部名に関数名を指定すると、
  .libはエントリー名を装飾したもの、
  .dllはエントリー名
・内部名を指定しない場合も同様

となるみたいですが、やっぱり問題が解決しません。
DLLがこうした使用を想定していないのかも…とも
思うのですが、今のままだとオーバーロードに対する
対応が中途半端に思えて、知らない機能や技術がある
かも…と思ったりしてます。

どうかよろしくお願いします。


シャノン  2004-03-17 05:40:16  No: 53313

不可能だと思いますけどねぃ…

関数名が勝手に装飾されるってことは、エクスポートする関数名を重複させることはできないってことです。
オーバーロードされたいくつかの関数の中から適切なものを特定するには引数の情報が必要ですが、GetProcAddress には関数名しか渡せません。
いや、言い換えれば、関数名の装飾こそが引数の情報(やその他)を表しているのですから、装飾名まで指定して GetProcAddress すれば可能ですが。

>DLLがこうした使用を想定していないのかも
たぶん想定してないでしょう。

>今のままだとオーバーロードに対する対応が中途半端
DLL はオーバーロードと言う概念がない C 言語でも作れますし、呼び出せますから。


ひげ犬  2004-03-19 00:16:55  No: 53314

シャノンさんレスありがとうございます。

>>DLLがこうした使用を想定していないのかも
>たぶん想定してないでしょう。

そうですか、と言う事は.defファイルでC++の関数を
使う場合は装飾名を使って、GetProcAddressにも
装飾名を渡すようにするしかないんですね。

>>今のままだとオーバーロードに対する対応が中途半端
>DLL はオーバーロードと言う概念がない C 言語でも作れますし、呼び出せますから。

たしかに、オーバーロードが無い言語の方が多いので、
DLLにそのための概念がなくても不思議じゃないですね。
すっきりしました。ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加