今晩は
「shared library」とDLLに関して追加質問させて下さい。
前回:
かずまさん書かれました:
>> DLL の場合、実行ファイルを生成する時に情報を与えることもできるし、与えないこともできます。
Q1: どんな場合、実行ファイルを生成する時に情報を与えることが必要でしょうか。
Q2: もし生成する時に情報を与えることが必要とすれば、DLLの意味がなくなり、「静的」になってしまったのでは?
Q3: DLLを生成するために、どうしてMS流ではわざわざソースコードの中に「余計」な文「__declspec(dllexport)」を挿入しなければならないのでしょうか。
「__declspec(dllexport)はアプリケーションロジックとは関係ないですね。
DLLとしない場合、ソースコードをいじらなくてはならなくなります。非常に不合理なやりかた?
宜しくお願い致します
「shared library」とDLL----追加質問
Re: 「shared library」とDLL----追加質問
暗黙のリンクを行う場合です。すなわち、さまよい さんが書きました: Q1: どんな場合、実行ファイルを生成する時に情報を与えることが必要でしょうか。
プログラムで LoadLibrary を実行しない場合です。
これは説明済みです。
sum.dll を作成するときにできた sum.lib は静的にリンクさまよい さんが書きました: Q2: もし生成する時に情報を与えることが必要とすれば、DLLの意味がなくなり、「静的」になってしまったのでは?
されますが、これには関数 sum の入り口しか存在せず、
そこから sum.dll 内の関数 sum を呼び出します。
sum.lib をリンクした main.exe は関数 sum の本体を
持っていないから、サイズは小さくなります。
DLL を作成するとき、エクスポートする関数名をリンクオプションさまよい さんが書きました: Q3: DLLを生成するために、どうしてMS流ではわざわざソースコードの中に「余計」な文「__declspec(dllexport)」を挿入しなければならないのでしょうか。
「__declspec(dllexport)はアプリケーションロジックとは関係ないですね。
DLLとしない場合、ソースコードをいじらなくてはならなくなります。非常に不合理なやりかた?
で指定すれば、__declspec(dllexport) を書かなくても構いません。 エクスポートする関数名がたくさんあるときは、
.defファイルに書いて、それを指定することもできます。
Re: 「shared library」とDLL----追加質問
そんなに M$ が嫌いなら、Windows でプログラムしなきゃいいでしょ。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: 「shared library」とDLL----追加質問
かずま 様
丁寧なご教授本当にありがとうございます。
かなり分かったような感じですけれども、追加質問させて下さい。
Q1. DLLを生成するために、必ずLIBも同時に生成されますね(同名?)。
これはLINUX系においても同じでしょうか。
Q2. 通常DLLに入れられた関数は当然「 エクスポート」のためだと思いますが、
なぜその名前を一つ一つ列挙しなければならないのでしょうか。
エクスポートする関数名がたくさんあるときは.defファイルに指定することは便利ですが、
これはLINUX世界においても同じやり方でしょうか。
また宜しくお願い致します。
丁寧なご教授本当にありがとうございます。
かなり分かったような感じですけれども、追加質問させて下さい。
Q1. DLLを生成するために、必ずLIBも同時に生成されますね(同名?)。
これはLINUX系においても同じでしょうか。
Q2. 通常DLLに入れられた関数は当然「 エクスポート」のためだと思いますが、
なぜその名前を一つ一つ列挙しなければならないのでしょうか。
エクスポートする関数名がたくさんあるときは.defファイルに指定することは便利ですが、
これはLINUX世界においても同じやり方でしょうか。
また宜しくお願い致します。
Re: 「shared library」とDLL----追加質問
__declspec(dllexport) をソースに記述せず、かつ、DLLさまよい さんが書きました: Q1. DLLを生成するために、必ずLIBも同時に生成されますね(同名?)。
生成時にリンクオプションの /EXPORT を指定しなかった
場合は、.libファイルは生成されません。ただし、生成
された .dllファイルは何もエクスポートしないので
使い道がありません。
Linux においては、説明済みです。さまよい さんが書きました: これはLINUX系においても同じでしょうか。
.soファイルを作成したとき、.aファイルは作成されません。
実行ファイル生成時に .soファイルを指定すると、
dlopen なしで、.dllファイル内の関数を呼び出せます。
DLL内部だけで使いたい関数があるかもしれません。さまよい さんが書きました: Q2. 通常DLLに入れられた関数は当然「 エクスポート」のためだと思いますが、
なぜその名前を一つ一つ列挙しなければならないのでしょうか。
Linux でエクスポートは聞いたことがありません。さまよい さんが書きました: エクスポートする関数名がたくさんあるときは.defファイルに指定することは便利ですが、
これはLINUX世界においても同じやり方でしょうか。
static でない関数は全部呼び出し可能なんだと思いますが、
調べてみないと分かりません。
質問です。
Windows で DLL を作成する環境をお持ちですか?
Linux で shared library を作成する環境をお持ちですか?
最初の回答の例を自分で試してみましたか?
Re: 「shared library」とDLL----追加質問
かずま 様
お世話になっております。
大変分かりやすくご解説頂き誠に有難うございます。
>>Windows で DLL を作成する環境をお持ちですか?
>>Linux で shared library を作成する環境をお持ちですか?
WindowsにするかLinuxにするか実は環境整備これからです。
ということはこれから開発しようとするAPPはC言語で実装した多量の実体(*.dllか *.so)をPythonでcallするのを想定しており、
こんな場合
WindowsとLinuxとどっちがdllの生成と動的にcallするのはより簡単かを調べています。
どうもLinux系のほうがシンプルな印象ですけれども、
ただLinux系の場合*.so(dll)を生成するために補助的にlibのようなファイルを生成しないのは逆に不思議に思います。
DLLの中の関数に関する情報ファイル(eg., まがいのLIB)を生成しなければ、
DLL関数を利用する側は「まがいのLIB」とリンクできず、リンクエラーが発生するのではと思いますが?
この辺ご説明頂ければ幸せです。
お世話になっております。
大変分かりやすくご解説頂き誠に有難うございます。
>>Windows で DLL を作成する環境をお持ちですか?
>>Linux で shared library を作成する環境をお持ちですか?
WindowsにするかLinuxにするか実は環境整備これからです。
ということはこれから開発しようとするAPPはC言語で実装した多量の実体(*.dllか *.so)をPythonでcallするのを想定しており、
こんな場合
WindowsとLinuxとどっちがdllの生成と動的にcallするのはより簡単かを調べています。
どうもLinux系のほうがシンプルな印象ですけれども、
ただLinux系の場合*.so(dll)を生成するために補助的にlibのようなファイルを生成しないのは逆に不思議に思います。
DLLの中の関数に関する情報ファイル(eg., まがいのLIB)を生成しなければ、
DLL関数を利用する側は「まがいのLIB」とリンクできず、リンクエラーが発生するのではと思いますが?
この辺ご説明頂ければ幸せです。
Re: 「shared library」とDLL----追加質問
Linux では、実行ファイルを生成するときに .soファイルを指定さまよい さんが書きました: どうもLinux系のほうがシンプルな印象ですけれども、
ただLinux系の場合*.so(dll)を生成するために補助的にlibのようなファイルを生成しないのは逆に不思議に思います。
DLLの中の関数に関する情報ファイル(eg., まがいのLIB)を生成しなければ、
DLL関数を利用する側は「まがいのLIB」とリンクできず、リンクエラーが発生するのではと思いますが?
しますから、リンカは何でもできるはずです。
呼び出し元には、静的リンクの関数を呼び出すようにみせて、
.soファイル内の関数を呼び出すような「つなぎの部分」を
生成することは可能です。
Re: 「shared library」とDLL----追加質問
つなぎの部分を私の妄想で作ってみました。
sum 1個だけではつまらないので、sum1、sum2 を追加してみました。
gcc -o main main.c sum.dll で実行ファイル生成しようとすると、
sum.dll があるため、 上記のような「つなぎの部分」を自動的に
作ります。sum.dll は、中に呼び出し可能な関数の情報を持っている
はずですから、このようなことができます。これを仮に libsum.c とすると、
内部で次のような手順でリンクを行えばよいでしょう。
#include <stdlib.h>
#include <dlfcn.h>
int sum(int n);
void sum1(void);
int sum2(char *s, const char *t);
struct FuncTable {
void (*func)(void);
const char *name;
};
struct FuncTable ft[3] = {
{ 0, "sum" },
{ 0, "sum1" },
{ 0, "sum2" },
};
void *so;
void set_ft(int i)
{
if (!so) {
so = dlopen("sum.so", RTLD_LAZY);
if (!so) exit(1);
}
ft[i].func = dlsym(so, ft[i].name);
if (!ft[i].func) exit(2);
}
int sum(int n)
{
if (!ft[0].func) set_ft(0);
return ((int (*)(int))ft[0].func)(n);
}
void sum1(void)
{
if (!ft[1].func) set_ft(1);
return ((void (*)(void))ft[1].func)();
}
int sum2(char *s, const char *t)
{
if (!ft[2].func) set_ft(2);
return ((int (*)(char *, const char *))ft[2].func)(s, t);
}
gcc -o main main.c sum.dll で実行ファイル生成しようとすると、
sum.dll があるため、 上記のような「つなぎの部分」を自動的に
作ります。sum.dll は、中に呼び出し可能な関数の情報を持っている
はずですから、このようなことができます。これを仮に libsum.c とすると、
内部で次のような手順でリンクを行えばよいでしょう。