Cygwin なんでも掲示板

一覧最新記事過去一覧 | 検索FAQアンテナHOME
(新規投稿・発言はできません)


スレッド

└◇579:
cygwinのライブラリを利用するVCアプリ [S.Taka] 09/01 00:37

 ├◇586:Re:cygwinのライブラリを利用するVCアプリ [水口] 09/09
 │└◇587:Re[2]:cygwinのライブラリを利用するVCアプリ [S.Taka] 09/10
 │ └◇603:Re[3]:cygwinのライブラリを利用するVCアプリ [ken] 09/21
 │  └◇604:Re[4]:cygwinのライブラリを利用するVCアプリ [S.Taka] 09/24
 │   └◇994:Re[5]:cygwinのライブラリを利用するVCアプリ [S.Taka] 03/16 <
 ├◇588:Re:cygwinのライブラリを利用するVCアプリ [やまもと] 09/10
 │└◇591:Re[2]:cygwinのライブラリを利用するVCアプリ [S.Taka] 09/13
 ├◇592:Re:cygwinのライブラリを利用するVCアプリ [S.Taka] 09/13
 │└◇873:Re[2]:cygwinのライブラリを利用するVCアプリ [森] 12/27
 │ └◇886:Re[3]:cygwinのライブラリを利用するVCアプリ [S.Taka] 01/02
 └◇763:Re:cygwinのライブラリを利用するVCアプリ [FX33V] 11/27
  └◇887:Re[2]:cygwinのライブラリを利用するVCアプリ [S.Taka] 01/02
   └◇888:Re[3]:cygwinのライブラリを利用するVCアプリ [S.Taka] 01/03
    └◇896:Re[4]:cygwinのライブラリを利用するVCアプリ [FX33V] 01/06


579● cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2002 09/01 00:37
はじめまして。 S.Taka と申します。

cygwinのライブラリを利用するDLLを作成し,
それをVisual C++ 6.0でコンパイルされるアプリケーション
から利用できるかどうか調べています。

結果としては、リンクまではうまくいくのですが、
プログラムを実行するとアプリケーションエラーが発生して
しまいます。 ただし、cygwinのライブラリを使わずにWin32APIのみを使用するDLLならば動作しました。

やり方が悪いのか、そもそも、そんなことはできないのか
どなたかご存知ないでしょうか?

実験したソース、コンパイル方法、実行結果を以下に書きます。


[testdll.c (cygwin のgccで作成するDLLのソース)]

#include <stdio.h>

void testfunc(void)
{
printf("testfunc\n"); /* MessageBoxとかなら動作する */
}

[testdll.def]

EXPORTS
testfunc

[main.c (VC6でコンパイルするソース)]

#include <stdio.h>

void testfunc(void);

int main()
{
testfunc();

return 0;
}

[ビルドログ]

$ gcc -shared testdll.c -o testdll.dll

$ lib /def:testdll.def
Microsoft (R) Library Manager Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

LIB : warning LNK4068: /MACHINE の指定がありません; IX86 をデフォルトとします
ライブラリ testdll.lib とオブジェクト testdll.exp を作成中

$ cl main.c testdll.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

main.c
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:main.exe
main.obj
testdll.lib

[結果]

$ ./main

---------------------------
main.exe - アプリケーション エラー
---------------------------
"0x610bd171" の命令が "0x00000108" のメモリを参照しました。メモリが "read" になることはできませんでした。


プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
---------------------------
OK キャンセル
---------------------------

[バージョン]
$ cmd /c ver
Microsoft Windows 2000 [Version 5.00.2195]

$ uname -a
CYGWIN_NT-5.0 HOGE 1.3.12(0.54/3/2) 2002-07-06 02:16 i686 unknown

$ gcc --version
2.95.3-5

$ cl /help
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
...
スレッド一覧


586● Re:cygwinのライブラリを利用するVCアプリ[ 水口 ] 2002 09/09 23:13
私も詳しくないのですが、Cygwinのgccで普通にコンパイル・リンクしたa.outは実行時にcygwin1.dllを必要とします。

a.outでなく.dllを作成したときどうなるかを調べて見られてはいかがでしょうか?

# cygwin環境の /bin をWindows風パスにしたものは、実行時のPATH変数に入っていますよね?

あるいは、gcc -mno-cygwin は試してみられましたか?

あまりお役にたてずにすみません。
スレッド一覧


587● Re[2]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2002 09/10 01:54
ご返信ありがとうございます

>私も詳しくないのですが、Cygwinのgccで普通にコンパイル・リンクしたa.outは実行時にcygwin1.dllを必要とします。

>a.outでなく.dllを作成したときどうなるかを調べて見られてはいかがでしょうか?

す、すいません。ちょっとわかりませんでした。
dllを作成したときどうなるか、とはgccで作成したDLLをさらにリンクするDLLをVCで作成してみよ。ということでしょうか?

# cygwin環境の /bin をWindows風パスにしたものは、実行時のPATH変数に入っていますよね?

すみません。ちょっと今確認できる環境にいないのでわかりませんが、VCのデバッガでcygwin1.dllがメモリにロードされていることは確認できているのでcygwin1.dll等のcygwin関連のファイルへのPATHは通っていると思います。

>あるいは、gcc -mno-cygwin は試してみられましたか?

はい。質問が舌足らずでしたが、gcc -mno-cygwinは試してうまくいっています。しかし、cygwinのXlibが使いたいのでcygwin1.dllをリンクする必要があります。


背景について全然お話していませんでした。
やりたいのは、PC-UNIX等で動くWindowsエミュレータWineをWindows上で動かしたいということです。

これができると何がうれしいかというと、WineはWin32APIをXlibを使用してエミュレートするのでWindowsアプリケーションをX上に表示することができます。そうなればcygwinのX上でWindowsアプリケーションとの連携作業もやりやすくなるし、Linux等からExcelやIEをLinux上にインストールせずともリモートで利用できるということです。(ライセンス的によいかは調べる必要がありますが)

それで、いきさつとしては、
1. WineをビルドするにはPosixエミュレートしているcygwinが適しているだろう。
      ↓
2. でもmakeが通らない。 (TT)
 . cygwinでWineをビルドするにはかなり大変そうだ。
      ↓
3. いや、まてよ。Wineをすべてビルドする必要があるのか?
kernel32.dll等エミュレートする必要がないものがほとんどだ。
user32.dllとgdi32.dllとおそらくcomctl32.dll、comdlg32.dllぐらいさえコンパイルできればAPIフックのテクニックを利用して目的が達成できるのではないか?
      ↓
4. ひとまず、user32.dll等のDLLを作成して、MSDN
等のサンプルプログラムから利用してみよう。
      ↓
5. でもその前に、cygwinのgccで作成するDLLがVCで利用できるのか試してみよう。
      ↓
6. 動かない。ショック !

というわけで、このような質問をさせていただきました。

しかし、このような質問をしているようでは実現は
遠そうですね…

長々と失礼いたしました。
スレッド一覧


603● Re[3]:cygwinのライブラリを利用するVCアプリ[ ken ] 2002 09/21 02:42
> 背景について全然お話していませんでした。
> やりたいのは、PC-UNIX等で動くWindowsエミュレータWineをWindows上で動かしたいということです。
>
> これができると何がうれしいかというと、WineはWin32APIをXlibを使用してエミュレートするのでWindowsアプリケーションをX上に表示することができます。そうなればcygwinのX上でWindowsアプリケーションとの連携作業もやりやすくなるし、Linux等からExcelやIEをLinux上にインストールせずともリモートで利用できるということです。(ライセンス的によいかは調べる必要がありますが)
>
cygwin-xfree mlで、同じようなことをしようという話題で
盛り上がっているようです。
http://cygwin.com/ml/cygwin-xfree/2002-09/msg00094.htmlから始まる一連のスレッドです。
参考までに。
スレッド一覧


604● Re[4]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2002 09/24 00:06
おお、すごいですね。
話しが盛り上がってついには、
David Fraserさんという方がSource Forgeに
XOpenWinというプロジェクトを立ち上げたようです。(http://xopenwin.sourceforge.net/)
私の方は時間とスキル不足でなかなか進展がないから、
こちらの方を期待しようかな。
スレッド一覧


994● Re[5]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2003 03/16 21:26
WineのCygwinへの移植をあきらめて、
同じWin32API実行環境であるPEACEの一部をCygwinに移植してみました。
興味のある方は、http://www.d1.dion.ne.jp/~sawanaka/peace/を参照してください。

では。
スレッド一覧


588● Re:cygwinのライブラリを利用するVCアプリ[ やまもと ] 2002 09/10 13:14
やまもとと申します。

下記のDLL化の作成方法が間違っています。

> [ビルドログ]
>
> $ gcc -shared testdll.c -o testdll.dll

URLの記述は、相手に断りを入れてないので、記述できませんが
googleで、下記の用語を全て入れて検索すれば、わかると思い
ます。

検索用語:DLL CygWin dlltool def

それでは、失礼します。
スレッド一覧


591● Re[2]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2002 09/13 23:34
やまもとさん情報ありがとうございます。返事がおそくなってすみません。

>下記のDLL化の作成方法が間違っています。
>
>> [ビルドログ]
>>
>> $ gcc -shared testdll.c -o testdll.dll
>
>URLの記述は、相手に断りを入れてないので、記述できませんが
>googleで、下記の用語を全て入れて検索すれば、わかると思い
>ます。
>
>検索用語:DLL CygWin dlltool def

検索してみました。もしかして、日本語で検索した一番最初の結果であるProject HeavyMoonさんの
Cygwin ユーザーズガイド [DLL のビルドと利用]の
ことをおっしゃっているのでしょうか?

DLLを作成するのに以下の5つのコマンドが必要とのことですが

gcc -s -Wl,--base-file,mydll.base -o mydll.dll mydll.o -Wl,-e,_mydll_init@12
dlltool --base-file mydll.base --def mydll.def --output-exp mydll.exp --dllname mydll.dll
gcc -s -Wl,--base-file,mydll.base,mydll.exp -o mydll.dll mydll.o -Wl,-e,_mydll_init@12
dlltool --base-file mydll.base --def mydll.def --output-exp mydll.exp --dllname mydll.dll
gcc -Wl,mydll.exp -o mydll.dll mydll.o -Wl,-e,_mydll_init@12

mydllの部分をtestdllに置き換えてやってみましたが、
最近のcygwinのgccでは1つ目のコマンドで

$ gcc -s -Wl,--base-file,testdll.base -o testdll.dll testdll.o -Wl,-e,_testdll_init@12

/usr/lib/libcygwin.a(libcmain.o): In function `main':
/home/Administrator/cygwin-snapshot-20020903-1/BUILD/i686-pc-cygwin/winsup/cygwin/../../../../winsup/cygwin/lib/libcmain
.c:31: undefined reference to `WinMain@16'
collect2: ld returned 1 exit status

というエラーがでてしまいます。どうもこのやり方は昔のバージョンのやりかたのようで、最近のgccでは
-shared オプションで簡単にDLLが作成できるみたいです。
このことは、最新のCygwin User's Guide(www.cygwin.com/cygwin-ug-net/dll.html)に記述されています。
スレッド一覧


592● Re:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2002 09/13 23:38
質問からだいぶ経ちましたが、私のほうもすこし状況が分かってきました。

現在、質問した後から分かったことは...

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;
}
スレッド一覧


873● Re[2]:cygwinのライブラリを利用するVCアプリ[ 森 ] 2002 12/27 09:57
http://www.mars.dti.ne.jp/~sohda/cygwin/java.html
にjniのサンプルがあります。

Widows用のjvmが何でコンパイルされているのか知りませんが、cygwin外のメインからcygwinで作ったdllを呼んでいますので、この真似をすればよいと思う。
スレッド一覧


886● Re[3]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2003 01/02 00:35
森さん、情報ありがとうございます。

なるほど、確かに早田さんの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で書いたような変なやり方をしなくても良いことが分かって
よかったです。ありがとうございました。
スレッド一覧


763● Re:cygwinのライブラリを利用するVCアプリ[ FX33V ] 2002 11/27 20:44
その後、進捗はいかがですか?
VCアプリでcygwinのライブラリをリンクできれば、
とても便利になるだろうと、興味をもって読ませて
頂きました。
スレッド一覧


887● Re[2]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2003 01/02 00:37
遅いレスポンスごめんなさい。

> その後、進捗はいかがですか?
> VCアプリでcygwinのライブラリをリンクできれば、

cygwin1.dll直接ではなく、間接的に使っている
libX11.dll等や自作のDLL等を使用するという限定つきならば、
以下の間に合わせ的プログラムでDLLからVC用インポート
ライブラリっぽいものが作れるようになったので、
作られたライブラリをVCのAPとリンクすれば一応動きはするようです。
(これを使ってVCで作った、XのHelloWorldっぽいプログラム
が動きました。)
興味があれば使ってみてください。

[コンパイル]
cl mkimplib.c

[実行]
以下を実行するとc:\cygwin\usr\X11R6\bin\libX11.libができる。

mkimplib.exe c:\cygwin\usr\X11R6\bin\libX11.dll

※ cl.exeやdumpbin.exeにパスが通っていないと動作しません。

----mkimplib.c---------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>

int main(int argc, char *argv[])
{
char buf[512];
char cmd[512];
char libfname[512];
char dllfname[512];
char *funcs[2048];
char *funcs2[2048];
char *p;
int nfuncs;
int i;
int j;
int len;
FILE *fp;

if (argc < 2) {
fprintf(stderr, "usage: mkimplib filename. ");
return EXIT_FAILURE;
}
if (_access(argv[1], 0) == -1) {
fprintf(stderr, "mkimplib: can not open %s. ", argv[1]);
perror("");
return EXIT_FAILURE;
}
sprintf(cmd, "dumpbin /exports %s", argv[1]);
fp = _popen(cmd, "r");
if (!fp) {
perror("mkimplib: popen error. ");
return EXIT_FAILURE;
}
for (i = 0, nfuncs = 0; ; i++) {
if (!fgets(buf, sizeof(buf), fp)) {
perror("mkimplib: dumpbin error. ");
return EXIT_FAILURE;
}
if (i > 18) {
if (buf[0] == '\n') break;
len = strlen(&buf[26]);
funcs[nfuncs] = (char *)malloc(len);
funcs2[nfuncs] = (char *)malloc(len);
memcpy(funcs[nfuncs], &buf[26], len);
funcs[nfuncs][len - 1] = '\0';
strcpy(funcs2[nfuncs], funcs[nfuncs]);
p = strrchr(funcs2[nfuncs], '@');
if (p) *p = '\0';

if (!(strcmp(funcs2[nfuncs], "alloca") == 0) &&
!(strcmp(funcs2[nfuncs], "setjmp") == 0) &&
!(strcmp(funcs2[nfuncs], "_alloca") == 0) &&
!(strcmp(funcs2[nfuncs], "_setjmp") == 0) &&
!(strcmp(funcs2[nfuncs], "atexit") == 0)) {
for (j = 0; j < nfuncs; j++) {
if (strcmp(funcs2[j], funcs2[nfuncs]) == 0) break;
}
if (j == nfuncs) nfuncs++;
}
}
}
_pclose(fp);

fp = fopen("__tmp__.cpp", "w");
if (!fp) {
perror("mkimplib: __tmp__.cpp open error. ");
return EXIT_FAILURE;
}
fprintf(fp, "static const char *m_pfuncnames[] = {\n");
for (i = 0; i < nfuncs; i++) {
fprintf(fp, "\"%s\",\n", funcs2[i]);
}
fprintf(fp, "};\n");
fprintf(fp, "static void *m_pfuncs[sizeof(m_pfuncnames) / sizeof(char*)];\n");
fprintf(fp, "\n");
for (i = 0; i < nfuncs; i++) {
fprintf(fp, "extern \"C\" __declspec(naked) void %s() { __asm jmp dword ptr [m_pfuncs + %d * 4] }\n", funcs2[i], i);
}
fprintf(fp, "\n");

fprintf(fp, "typedef void *HANDLE;\n");
fprintf(fp, "HANDLE __stdcall LoadLibraryA(const char *lpFileName);\n");
fprintf(fp, "void *GetProcAddress(HANDLE hModule, const char *lpProcName);\n");
fprintf(fp, "int __stdcall MessageBoxA(HANDLE hWnd, const char *lpText, const char *lpCaption, unsigned int uType);\n");
fprintf(fp, "\n");

p = strrchr(argv[1], '\\');
if (p) {
strcpy(dllfname, p + 1);
} else {
p = strrchr(argv[1], '/');
if (p) {
strcpy(dllfname, p + 1);
} else {
strcpy(dllfname, argv[1]);
}
}

fprintf(fp, "class Dummy {\n");
fprintf(fp, "public:\n");
fprintf(fp, "\tDummy() {\n");
fprintf(fp, "\t\tint i;\n");
fprintf(fp, "\t\tHANDLE hLibrary = LoadLibraryA(\"%s\");\n", dllfname);
fprintf(fp, "\t\tif (!hLibrary) {\n");
fprintf(fp, "\t\t\tMessageBoxA(0, \"%s がロードできません。\", 0, 0);\n", dllfname);
fprintf(fp, "\t\t\treturn;\n");
fprintf(fp, "\t\t}\n");
fprintf(fp, "\t\tfor (i = 0; i < sizeof(m_pfuncnames) / sizeof(char*); i++) {\n", nfuncs);
fprintf(fp, "\t\t\tm_pfuncs[i] = GetProcAddress(hLibrary, m_pfuncnames[i]);\n");
fprintf(fp, "\t\t}\n");
fprintf(fp, "\t}\n");
fprintf(fp, "};\n");
fprintf(fp, "static Dummy dummy;\n");
fprintf(fp, "\n");
fclose(fp);

strcpy(libfname, argv[1]);
p = strrchr(libfname, '.');
if (p) {
strcpy(p, ".lib");
} else {
strcat(libfname, ".lib");
}
system("cl /c __tmp__.cpp");
sprintf(cmd, "lib __tmp__.obj /out:%s", libfname);
system(cmd);

return EXIT_SUCCESS;
}

------------------------------------------
スレッド一覧


888● Re[3]:cygwinのライブラリを利用するVCアプリ[ S.Taka ] 2003 01/03 00:06
すいません。動かないソースを書き込んでしまいました。

こっちなら動くと思います。

-----------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>

int main(int argc, char *argv[])
{
        char buf[512];
        char cmd[512];
        char libfname[512];
        char dllfname[512];
        char *funcs[2048];
        char *funcs2[2048];
        char *p;
        int nfuncs;
        int i;
        int j;
        int len;
        FILE *fp;

        if (argc < 2) {
                fprintf(stderr, "usage: mkimplib filename. ");
                return EXIT_FAILURE;
        }
        if (_access(argv[1], 0) == -1) {
                fprintf(stderr, "mkimplib: can not open %s. ", argv[1]);
                perror("");
                return EXIT_FAILURE;
        }
        sprintf(cmd, "dumpbin /exports %s", argv[1]);
        fp = _popen(cmd, "r");
        if (!fp) {
                perror("mkimplib: popen error. ");
                return EXIT_FAILURE;
        }
        for (i = 0, nfuncs = 0; ; i++) {
                if (!fgets(buf, sizeof(buf), fp)) {
                        perror("mkimplib: dumpbin error. ");
                        return EXIT_FAILURE;
                }
                if (i > 18) {
                        if (buf[0] == '\n') break;
                        len = strlen(&buf[26]);
                        funcs[nfuncs] = (char *)malloc(len);
                        funcs2[nfuncs] = (char *)malloc(len);
                        memcpy(funcs[nfuncs], &buf[26], len);
                        funcs[nfuncs][len - 1] = '\0';
                        strcpy(funcs2[nfuncs], funcs[nfuncs]);
                        p = strrchr(funcs2[nfuncs], '@');
                        if (p) *p = '\0';

                        if (!(strcmp(funcs2[nfuncs], "alloca") == 0) &&
                         !(strcmp(funcs2[nfuncs], "setjmp") == 0) &&
                         !(strcmp(funcs2[nfuncs], "_alloca") == 0) &&
                         !(strcmp(funcs2[nfuncs], "_setjmp") == 0) &&
                         !(strcmp(funcs2[nfuncs], "atexit") == 0)) {
                                for (j = 0; j < nfuncs; j++) {
                                        if (strcmp(funcs2[j], funcs2[nfuncs]) == 0) break;
                                }
                                if (j == nfuncs) nfuncs++;
                        }
                }
        }
        _pclose(fp);

        fp = fopen("__tmp__.cpp", "w");
        if (!fp) {
                perror("mkimplib: __tmp__.cpp open error. ");
                return EXIT_FAILURE;
        }
        fprintf(fp, "static const char *m_pfuncnames[] = {\n");
        for (i = 0; i < nfuncs; i++) {
                fprintf(fp, "\"%s\",\n", funcs2[i]);
        }
        fprintf(fp, "};\n");
        fprintf(fp, "static void *m_pfuncs[sizeof(m_pfuncnames) / sizeof(char*)];\n");
        fprintf(fp, "\n");
        for (i = 0; i < nfuncs; i++) {
                fprintf(fp, "extern \"C\" __declspec(naked) void %s() { __asm jmp dword ptr [m_pfuncs + %d * 4] }\n", funcs2[i], i);
        }
        fprintf(fp, "\n");

        fprintf(fp, "typedef void *VOIDPTR;\n");
        fprintf(fp, "extern \"C\" {\n");
        fprintf(fp, "VOIDPTR __stdcall LoadLibraryA(const char *lpFileName);\n");
        fprintf(fp, "VOIDPTR __stdcall GetProcAddress(VOIDPTR hModule, const char *lpProcName);\n");
        fprintf(fp, "int __stdcall MessageBoxA(VOIDPTR hWnd, const char *lpText, const char *lpCaption, unsigned int uType);\n");
        fprintf(fp, "}\n");

        p = strrchr(argv[1], '\\');
        if (p) {
                strcpy(dllfname, p + 1);
        } else {
                p = strrchr(argv[1], '/');
                if (p) {
                        strcpy(dllfname, p + 1);
                } else {
                        strcpy(dllfname, argv[1]);
                }
        }

        fprintf(fp, "class Dummy {\n");
        fprintf(fp, "public:\n");
fprintf(fp, "\tDummy() {\n");
        fprintf(fp, "\t\tint i;\n");
        fprintf(fp, "\t\tVOIDPTR hLibrary = LoadLibraryA(\"%s\");\n", dllfname);
        fprintf(fp, "\t\tif (!hLibrary) {\n");
        fprintf(fp, "\t\t\tMessageBoxA(0, \"%s がロードできません。\", 0, 0);\n", dllfname);
        fprintf(fp, "\t\t\treturn;\n");
        fprintf(fp, "\t\t}\n");
        fprintf(fp, "\t\tfor (i = 0; i < sizeof(m_pfuncnames) / sizeof(char*); i++) {\n", nfuncs);
        fprintf(fp, "\t\t\tm_pfuncs[i] = GetProcAddress(hLibrary, m_pfuncnames[i]);\n");
fprintf(fp, "\t\t}\n");
        fprintf(fp, "\t}\n");
        fprintf(fp, "};\n");
        fprintf(fp, "static Dummy dummy;\n");
        fprintf(fp, "\n");
        fclose(fp);

        strcpy(libfname, argv[1]);
        p = strrchr(libfname, '.');
        if (p) {
                strcpy(p, ".lib");
        } else {
                strcat(libfname, ".lib");
        }
        system("cl /c __tmp__.cpp");
        sprintf(cmd, "lib __tmp__.obj /out:%s", libfname);
        system(cmd);

        return EXIT_SUCCESS;
}

-----------------------------------------------------
スレッド一覧


896● Re[4]:cygwinのライブラリを利用するVCアプリ[ FX33V ] 2003 01/06 09:16
レスありがとうございます。

> 作られたライブラリをVCのAPとリンクすれば一応動きはするようです。
> 興味があれば使ってみてください。

チャレンジしてみます。
スレッド一覧

早田のホームページへ
CGIROOM