DLL作成

[戻る]
ame 2002/12/04(水) 17:14:03
DLLを作成するにあたりVC++ TipsのDLLサンプルを参考にさせてもらったのですが
Sampleとまったく同じように作るとエラーはでないのですが、実行しても結果が表示されませ
ん。どうもLoadlibraryでDLLがよめていないようです。DLL側の拡張子をcppからcにかえると
うまく動くのですが、Sampleにもあったようにextern"C"を使ってもうまくいかないのは何故で
しょうか?初心者なもので、初歩的な質問で申し訳ないのですが教えてください。

RAPT 2002/12/04(水) 20:19:49
こんばんは、RAPTです。

???
DLLを作成し、実行しても結果が出ない? 当然では? DLLを作成しただけで、
実行可能ファイルを作成したわけではないのだから。

Windows98/VC++6.0std/SDK-may2002/ATL3.0/WTL7.0

wood 2002/12/04(水) 22:05:12
RAPTさんへ
>DLLを作成し、実行しても結果が出ない? 当然では?
>実行可能ファイルを作成したわけではないのだから。

チョット違う感じがします
こんなこと言ってますから

>DLL側の拡張子をcppからcにかえるとうまく動くのですが、

ソースの拡張子変えたくらいでDLLのコンパイル・リンクが
EXEのコンパイル・リンクに切り替わらないと思いますけど

多分この「ame さん」は*.MAPの生成の仕方、
生成された*.MAPの見方
*.DEFの作り方
*.DEFがリンク作業にどんな影響があるのか知らず

例題の説明にある
>ちなみに今回の例では ?add@@YAHHH@Zです。

?add@@YAHHH@Zの部分が Cとしてコンパイルされた場合と
C++としてコンパイルされた場合違う値になる
ことを良く理解できていないのだと思われますけど?

説明に書いてあったのをそのまま使ったんではないですかね?

>・declspecを使った場合
>  GetProcAddress(hDLL,"add")
>・DEFファイルを使った場合
>  GetProcAddress(hDLL,"_add@8")
この説明をもう少し理解すれば解決になるのではないでしょうか

ame 2002/12/06(金) 15:23:12
>・declspecを使った場合
>  GetProcAddress(hDLL,"add")
>・DEFファイルを使った場合
>  GetProcAddress(hDLL,"_add@8")

自分でもこのあたりが理解できていないように思います。
いくつか、参考文献をみてはいるのですが、
VCで作っているのに、Cとしてコンパイルされてしまうという意味が理解できません。

単にdeclspecとDEFファイルのどちらを使ったかによって、関数のエクスポート名の
記述をかえればいいというわけではないのでしょうか?

ちなみに自分で作ったソースはDLL名を"add"、関数名を"MYFUNC"にしており、
明示的リンクをさせたいので、以下のようにしました。
void main()
{
    HINSTANCE hDLL;

    hDLL=LoadLibrary("add");
    if(hDLL!=NULL)
    {
        pFunc=(MYFUNC)GetProcAddress(hDLL,"MyFunc");
        if(!pFunc)
        {
            FreeLibrary(hDLL);
            return;
        }
        printf("answer=%d\n",pFunc(1,3));
    }
    FreeLibrary(hDLL);
}

wood 2002/12/07(土) 00:42:50
>Cとしてコンパイルされてしまうという意味が理解できません。
ソースプログラムの拡張子でCかC++にコンパイルされるようになっています
*.CはCとして
*.CPPはC++としてコンパイルされるようになっています

>・DEFファイルを使った場合
>  GetProcAddress(hDLL,"_add@8")

この場合の「_add@8」のうち「add@」を除いた部分がコンパイル状況
(CかC++)によって変わります
どのように変わるのかは*.MAPの生成をして自分で確認してください

>例題の説明にある
>>ちなみに今回の例では ?add@@YAHHH@Zです。
これは「*.CはCとして」の結果のはずです

*.CPPの場合翻訳時点で実行時に使用されるランタイムがCの場合と異なる
ため「YAHHH@Z」この辺の修飾子が変わるはずです

あなたの行いたい方法は*.DEFを使った方法を望まないようですけど
どうなのでしょうか?

再度、解説をご確認ください

尚、*.DEFを使うのはDLL作成に限らないのでこの辺の学習をしてみては
どうでしょうか

wood 2002/12/07(土) 00:45:28
追伸
私はMFC拡張DLL 1本しか作ったことしかありません
WIN32DLLについてはよく分かりかねます

YuO [E-Mail] 2002/12/09(月) 01:02:27
説明文の,
> ・declspecを使った場合
>   GetProcAddress(hDLL,"add")
> ・DEFファイルを使った場合
>   GetProcAddress(hDLL,"_add@8")
これが逆なんですね。

declspec(dllexport)を利用してエクスポートした場合,
リンカに渡される修飾名がそのままエクスポート名として使われます。
修飾名は,
C言語でcdecl呼び出しの場合,VC++は関数名の先頭に_を付けるだけです。
C言語でstdcall呼び出しの場合,VC++は関数名の先頭に_を,末尾に@と引数として要求するバイト数を付けます。
C++言語の場合は,関数の多重定義ができるので,関数名を引数に合わせて修飾します。
今回の@@YAHHH@Zは,引数としてintをふたつ受け取りintを返す,という意味になります。
#これもVC++の場合。

DEFファイルの場合,DEFファイルに記述された名前がそのままエクスポート名として使われます。

古いスレッドには追加発言できません。