Cygwin なんでも掲示板

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


スレッド

└◇763:
Re:cygwinのライブラリを利用するVCアプリ [FX33V] 11/27 20:44

 └◇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


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