- Community Home
- >
- HPE Community, Japan
- >
- HP-UX
- >
- HP-UX General
- >
- 共有ライブラリのエントリポイントについて
カテゴリ
Company
Local Language
フォーラム
ディスカッションボード
フォーラム
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
ディスカッションボード
ディスカッションボード
ディスカッションボード
ディスカッションボード
フォーラム
ディスカッションボード
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
フォーラム
ブログ
- RSS フィードを購読する
- トピックを新着としてマーク
- トピックを既読としてマーク
- このトピックを現在のユーザーにフロートします
- ブックマーク
- 購読
- 印刷用ページ
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-18-2004 06:30 PM
09-18-2004 06:30 PM
共有ライブラリのエントリポイントについて
共有ライブラリを作成しているのですが、
資源の初期化を、ライブラリがロードされた時点で行いたいと考えています。
WindowsのDllMain()のような、
共有ライブラリのエントリポイントを提供する関数はないのでしょうか?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-22-2004 10:14 AM
09-22-2004 10:14 AM
共有ライブラリのエントリポイントについて
DLLエントリーポイントは詳しくは分かりませんが、
Windows OS 特有なのでしょう。
UNIX では共有ライブラリの初期化などの概念はありません。
>WindowsのDllMain()のような、
>共有ライブラリのエントリポイントを提供する関数はないのでしょうか?
ないと思います。
man shl_load を読んでみた方が良いです。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-22-2004 11:47 AM
09-22-2004 11:47 AM
共有ライブラリのエントリポイントについて
"初めて実行される" をきっかけに出来ないかと、
以下のようなのを試しました。例えば、
---- sub.c
static int flag = 0;
sub()
{
if (flag == 0) {
flag = 1;
printf("initialized\n");
}
printf("sub is called by pid %d\n",
getpid(0) );
}
これから、
$ cc +z -c sub.c
$ ld -b -o sub.sl sub.o
で共有ライブラリを作り、
---- main.c
#include
main()
{
sub();
sleep(10);
}
というmainをコンパイル。
$ cc main.c sub.sl
できたa.outを、2つのwindow で順に走らせる(つまり、一つ前のが終わらないうちにもう一つ並列実行する)
$ ./a.out
initializing
sub is called by pid 27811
$ ./a.out
initializing
sub is called by pid 27812
ということで、2つのプロセスがこのライブラリを共有しているわけですが、sub.sl中の static 変数 "flag" は、プロセスごとに(異なった)実体があることが分かります。(もし本当にこの変数の実体が1つしかないなら、2つめに起動したプロセスでは flag が 1になっており、"initializing"は表示されないはずです。
このことから、もし、共有ライブラリで、ロードされた時点で自動的に(一回)起動される関数があったとしても、リソースをそのライブラリで宣言した変数で管理する限りにおいて、それが見えるのはロードのきっかけとなったプロセスだけでしょう。
そうではなく、共有ライブラリがプロセスによって
"ロード"されるごとに、何らかの初期化ルーチンが
走るのを期待したい、ということであれば、ライブラリを共有ライブラリとしてリンクした場合と、スタティックライブラリとしてarchiveリンクした場合と、動作が異なることになります。
テレコム担当者さんが書いたように、もし、共有ライブラリを shl_load()やdlopen()を使って明示的に読み込むのであれば (通常は dld が自動でやります)
読み込んだ後、例えば、"ライブラリ名_init" という関数名があればそれを一回だけ呼び出す、というロジックを組み込むことは可能でしょう。
ただしこの場合でも、リソースの管理を共有ライブラリのグローバル変数に置くのでは他のプロセスには伝わりません。(共有メモリセグメントを割り付けるところまでやれば、複数プロセスから共有できるリソースにはなりますが、大変そう。)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-23-2004 12:52 PM
09-23-2004 12:52 PM
共有ライブラリのエントリポイントについて
上記URLに共有ライブラリのイニシャライザーという項目があります。
共有ライブラリをロード・アンロードする際に実行するルーチンを指定できるようです。
例えば、以下の様なります。
mylib.c:
#include
#include
void my_init(shl_t hdl, int op)
{
if (op) {
printf("my library is now loading\n");
} else {
printf("my library is now unloading\n");
}
}
my_func(int i) {
return (i < 0)?i:-i;
}
t.c:
#include
#include
main()
{
int (*func)(int);
shl_t hdl;
hdl = shl_load("mylib.sl", BIND_IMMEDIATE, 0);
shl_findsym(&hdl, "my_func", TYPE_PROCEDURE, (void *)&func));
printf("%d\n", (*func)(-13));
shl_unload(hdl);
}
$ cc -c +z mylib.c
$ ld -b -o mylib.sl +I my_init mylib.o
$ cc t.c
$ a.out
my library is now loading
-13
my library is now unloading
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-23-2004 04:45 PM
09-23-2004 04:45 PM
共有ライブラリのエントリポイントについて
ライブラリロード時の初期化はisaoさんの方法で
実現できそうです。
質問に挙げ忘れましたが、
DllMain()は、DLLをロードしているプロセスが
スレッドを作成した場合にも呼び出されるのですが、
UNIXでこれと同等の処理を行うことは
不可能なのでしょうか?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-25-2004 07:03 AM
09-25-2004 07:03 AM
共有ライブラリのエントリポイントについて
"isao"さんのサンプルはshl_load()まで使った凝ったものなので、単純にした追試をしました。
mylib.c
#include
#include
static int flag = 1;
void
my_init(shl_t hdl, int op)
{
if (op) {
printf("my library is now loading\n");
++flag;
} else {
printf("my library is now unloading\n");
}
}
my_func(int i)
{
printf("my func : %d, flag : %d\n", i, flag);
}
で、main.cは単に、
#include
main()
{
my_func(10);
sleep(10);
}
にしました。
$ cc +z -c mylib.c
$ ld -b -o mylib.sl +I my_init mylib.o
$ cc main.c mylib.sl
で実行形式ファイルを作り、a.outを2つのwindowで順に実行したところ、
$ ./a.out
my library is now loading
my func : 10, flag : 2
で、もう一つ並列に実行しても、
$ ./a.out
my library is now loading
my func : 10, flag : 2
となる。ですので初期化関数は、共有ライブラリがファイルからメモリにロードされる時点で一回だけ実行される、という意味合いのものではなく、プロセスにアタッチされる時点でそれぞれ一回実行される、
共有ライブラリ中のデータは、プロセスごとに異なった空間におかれる、ということが分かります。
nackyさんのおっしゃる "DLLをロードしている
プロセスがスレッドを作成するごとに呼び出される。" ということですが、うーん、HP-UXとWindows OSとで、プロセスとスレッドという用語の意味が若干異なるような気が。
上のサンプルプログラムmain()でpthread_create()でthreadを作っても共有ライブラリの再度のロードや初期化は起こりません。一方、このmain()で fork/exec を使って新しいプロセスを作るとき、新しいプロセスが同じ共有ライブラリとリンクしてあれば、それをアタッチするときに初期化ルーチンは呼ばれるはずです。
ですので、
"資源の初期化を、ライブラリがロードされた時点で行いたい" ということが、"共有ライブラリが初めてファイルからメモリに読まれた時点で一回だけ実行する関数を持ちたい" ということであれば、"ファイルからメモリへ” のきっかけの部分は ld の +I で実現できますが、”一回だけ" というのが苦しい。外部(共有メモリ? ファイル?) に何らかのフラグを持たないといけないと思います。 (同様に unloadされたとき、最後のunloadで一回だけ呼ぶ、てのも何らかの細工を要するような)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-25-2004 07:23 AM
09-25-2004 07:23 AM
共有ライブラリのエントリポイントについて
どうやら、
資源初期化の契機を提供するI/Fを
ライブラリに持たせるのが1番無難なように思われますので
とりあえず、それを検討したいと思います。
念のため質問のほうは未解決にしておきますので、
情報お持ちの方は、引き続きご提供の程、宜しくお願いいたします。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-25-2004 08:18 AM
09-25-2004 08:18 AM
共有ライブラリのエントリポイントについて
関して。M社のサイトからあんまり引用するのはまずいので,下手な訳ですが...
DllMain
DllMain関数は、ダイナミックリンクライブラリ(DLL)中で、オプションのエントリポイントである。もしこの関数が(DLLの定義中で)使われると、processやthreadが初期化、終了したとき,または、LoadLibrary, FreeLibraryの呼び出し時にsystem(OSのことか?)から呼び出される。
...
fdwReason
DLL_PROCESS_ATTACH
DLL_THREAD_ATTACH 現行processが新しい
threadを作っている。systemは現在このprocessに
attachされているすべてのDLLのこのエントリポイントを(fdvReason=DLL_THREAD_ATTACHにして)呼び出す。
DLL_THREAD_DETACH
DLL_PROCESS_DETACH
ということは、HP-UX では ld の +I entty_point
でDLL_PROCESS_ATTACH/DLL_PROCESS_DETACHに相当することは実現できそうですが、DLL_THREAD_ATTACH/DLL_THREAD_DETACH は、... 相当する機能をつけるとすれば、
-- thread を作るときには pthread_create()の3番目の引数で関数を指定するわけですから、その関数の頭で初期化動作を行えば, DLL_THREAD_ATTACHに相当する動作は出来る。
-- threadが pthread_exit()を呼んで終わるときは、
後始末関数を明示的に呼べますが、非同期cancelなどで終わるのがある場合は、pthread_cleanup_push()関数で、clean up関数を登録しておけば、thread終了時に呼んでくれるので、DLL_THREAD_DETACHに相当する動作も実現できます。
(それでも "...is called by the system when processs and threads are initialized..." が良く分からない。OSが呼ぶのですかねえ。HP-UXでは、プロセスのコンテキストでdynamic loaderが呼んでくれるはず。だから"system wide" のリソース割付は
単に変数に値を入れるだけでは駄目で、そのプロセスにしか有効ではない。複数プロセス間で共通リソースとして持つには、共有メモリか、ファイルか、(またはmemory mapped fileか?) で持つことになります。)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-25-2004 08:46 AM
09-25-2004 08:46 AM
共有ライブラリのエントリポイントについて
>pthread_create()の3番目の引数で関数を指定するわけですから、
>その関数の頭で初期化動作を行えば,
>DLL_THREAD_ATTACHに相当する動作は出来る。
pthread_create()を呼び出すのは、共有ライブラリを使用する側で、
ライブラリからその呼び出し関数を指定するのは不可能では?
Windowsでは、DLLを使用している側がスレッドを作成すると、
システムがDllMain()をDLL_THREAD_ATTACHパラメータとともに呼び出し、
DLLはここで新規スレッドに対する初期化を行えるわけです。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
09-25-2004 01:47 PM
09-25-2004 01:47 PM
共有ライブラリのエントリポイントについて
> 作成すると、システムがDllMain()
> をDLL_THREAD_ATTACHパラメータとともに
> 呼び出し、DLLはここで新規スレッドに対する
> 初期化を行えるわけです。
おっしゃるとおり、HP-UXのthreadモデルでは、
thread作成時にDLL全部の初期化ルーチンをもう一回呼ぶ、なんて機能はもともとありません。 pthread_create()のman pageを見ると、"新しいスレッドが作成されるときには、argを唯一のパラメータとする (3番目の引数で指定した) start_routine()を実行します。" とありますから、"thread作成時に何らかの動作をさせるには、pthread_create()で指定した関数の前のほうに書くしかありません。例えば、この中で、"isao"さんが例に書いたように、ライブラリごとのthread作成時に呼びたい/呼ばれたい関数の名前を決めておけば、shl_findsym()を使ってエントリアドレスを得て呼び出すことは可能でしょう。ですが、Windowsのthreadモデルと同じにはなりませんね。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
07-07-2005 03:25 PM
07-07-2005 03:25 PM
共有ライブラリのエントリポイントについて
HP-UX 11.23の C言語のreferenceを読んでいたら
INIT と FINI という Pragmaがありました。
( ファイルは
/opt/ansic/html/C/guide/pragmas.htm
です。)
INIT Pragma
#pragma INIT "string"
初期化関数名を指定する。この関数は引数なしで、戻り値もなし。この関数は、プログラムの開始時か、または、共有ライブラリがロードされるときに実行される。
FINI Pragma
#pragma FINI "string"
この関数は、プログラムが停止、(libcの exit()を呼ぶ、または、main()からreturnする、または、_start関数からreturn する、または、これを含む共有ライブラリがメモリから unloadされる、時に実行されれる。
とありますね。DllMain()とは同じにはならないかも知れませんが、"ライブラリがロードされた時点で自動的に呼び出す"というのは出来そうですね。