▼スレッド
│
└◇592:Re:cygwinのライブラリを利用するVCアプリ [S.Taka] 09/13 23:38
└◇873:Re[2]:cygwinのライブラリを利用するVCアプリ [森] 12/27
└◇886:Re[3]:cygwinのライブラリを利用するVCアプリ [S.Taka] 01/02
質問からだいぶ経ちましたが、私のほうもすこし状況が分かってきました。スレッド一覧
現在、質問した後から分かったことは...
1. ようやくcygwin1.dllのビルド方法とgdbの使い方が分かり始めてきたので、gdbを使ってどこで死んでいるかを調べてみると、cygheap.hのcygheap_fdgetコンストラクタ内の
296 if (fd >= 0 && fd < (int) cygheap->fdtab.size
297 && *(fh = cygheap->fdtab + fd) != NULL)
でcygheapがNULLになっているから死んでしまうようだ。
なんとなくcygwin1.dllの初期化ルーチンがまったく動作していないっぽい。
2. いろいろWeb上の情報を調べていくうちに、かつて、Mumit KhanさんがnoncygwinなアプリケーションからでもcygwinのDLLが使えるようにしてくれていたことがわかった。Mumit KhanさんのWebページにはExcel等からよびだすDLLの作成例がある。どうやらDLLのエントリポイントの関数を cygwin_noncygwin_dll_entryにすればよかったようだ。でも、現在のcygwin1.dllではうまくいかないようで、_cygwin_noncygwin_dll_entryのソースのコメントをみると
/* OBSOLETE: This is only provided for source level compatibility. */
int WINAPI _cygwin_noncygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr) \
{ \
return _cygwin_dll_entry (h, reason, ptr); \
} \
とOBSOLETEになってしまっている。
3. それでも、むりやりcygwin1.dllの初期化処理を呼んでやればよさそうな気がしたのでこの書き込みの最後の様にcygwin1.dllの初期化処理cygwin_crt0関数を呼んであげたらなんとか動作するようになった。
・・・
3の方法でなんとかcygwinのライブラリを使用するDLLをVCから使うことができたのですが、この方法では、main側のソースがないとどうしようもなく、今回の目的にはそいません。
引き続き、なにか情報があればおねがいします。
----------------------------------------------------------------
[testdll.c]
#include <stdio.h>
extern void cygwin_crt0(void *pmain);
void __stdcall initCygwinCRT(int (*pmain)(int argc, char **argv))
{
cygwin_crt0(pmain);
}
void __stdcall testfunc(void)
{
printf("testfunc\n");
}
[testdll.def]
EXPORTS
testfunc@0
initCygwinCRT@4
[main.c]
#include <stdio.h>
#include <windows.h>
void __stdcall initCygwinCRT(int (*pmain)(int argc, char **argv));
void __stdcall testfunc(void);
int main2(int argc, char **argv)
{
testfunc();
return 0;
}
int main()
{
initCygwinCRT(main2);
return 0;
}
http://www.mars.dti.ne.jp/~sohda/cygwin/java.htmlスレッド一覧
にjniのサンプルがあります。
Widows用のjvmが何でコンパイルされているのか知りませんが、cygwin外のメインからcygwinで作ったdllを呼んでいますので、この真似をすればよいと思う。
森さん、情報ありがとうございます。スレッド一覧
なるほど、確かに早田さんのJNIのサンプルで作るDLLは
cygwin1.dllを使用していますね。サンプルも動く
ことを確認できました。
違いを考えてみると、私の試したやり方は、DLL
の事前ロード(こう言い方でよいのかしら?)で、
おそらくJavaのVMはDLLをLoadLibrary APIを使って
遅延ロードする方法だと思いましたので、次のような
プログラムを作って実験してみましたところうまくいき
ました。(なお、testdll.dllはgccで作ったDLLです)
---------------------------------------------
#include <stdio.h>
#include <windows.h>
int main()
{
HMODULE hLibrary;
void (*pfnTestFunc)(void);
hLibrary = LoadLibrary("testdll.dll");
pfnTestFunc = (void (*)(void))GetProcAddress(hLibrary, "testfunc");
pfnTestFunc();
return 0;
}
---------------------------------------------
なぜ、この方法ならばうまくいくのかが分かっていませんが、
592で書いたような変なやり方をしなくても良いことが分かって
よかったです。ありがとうございました。