使用winelib在linux下调用DLL

三月 20th, 2010 | 318 次阅读
Tags: 技术 Linux Posted in 技术杂项 :-)说点什么吧

      相信Wine这个工具对很多使用linux系统的人来说都不会陌生,它能帮你在Linux环境下直接运行windows程序(目前还不能做到100%支持)。但是很少有人知道wine所附带的开发工具winelib,它现在已经是用来编译Wine本身的工具了。使用winelib,我们可以编译可以使wine来加载的程序,这个程序既可以调用Linux下的POSIX库,也可以调用windows的system call。那么,我们就可以用winelib来编译一个需要调用windows环境的dll,但是在Linux环境下运行的程序。

      使用winelib来编译调用了dll的程序在源代码上,与为windows环境写的那种是一样的,唯一不同的是其编译方式。在这里我们有一个dll文件junk.dll,使用winedump工具对其进行解析:

$winedump spec junk.dll
Contents of junk.dll: 14168 bytes
1 named symbols in DLL, 1 total, 1 unique (ordinal base = 1)
Done dumping junk.dll
Export   1 - 'HelloWorld' ... [Ignoring]

      从winedump的运行结果可以看出,这个dll里面包含了一个名为HelloWorld的函数可供调用。同时会生成一份.spec文件(在这里就是junk.spec),里面记录了该DLL内可调用的函数名(不保含其原型)。

      这个HelloWorld函数的实现是:

1 DLLIMPORT void HelloWorld ()
2 {
3     MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
4     printf("%s\n","Test");
5 }

      也就是调用windows的消息框显示一段信息,之后在标准输出流打印出Test。

      现在我们写一个调用该DLL并使用这个HelloWorld函数的演示程序,代码文件junk.c:

01 #include <unistd.h>
02 #include <stdio.h>
03 #include <windows.h>
04 int main(int argc, char* argv[])
05 {
06 char bufr[256];
07 HANDLE h;
08 void (/*WINAPI?*/ *say)(void); 
09
10 gethostname(bufr, sizeof(bufr));
11 strcat(bufr, " says, 'Howdy World!'");
12 MessageBox(NULL, bufr, "Junk", MB_OK);
13
14 h = LoadLibrary("junk.dll");
15 if(!h) exit(1);
16 say = GetProcAddress(h, "HelloWorld");
17 //say = GetProcAddress(h, MAKEINTRESOURCE(1));
18
19 sprintf(bufr,"%d",say);
20 MessageBox(NULL, bufr, "Junk", MB_OK);
21 say();
22
23 return(0);
24 }

      这里可以看到,这个程序加载了junk.dll,获取了HelloWorld这个函数的地址,并执行了这个程序。接下来让我们编译这个程序,使用这个命令:winegcc -o junk junk.c ,这样就生成了两个文件:junk.exe和junk.exe.so,其中junk.exe是一个shell脚本,它会调用wine来加载junk.exe.so,junk.exe.so就是wine所要加载的二进制程序,所以我们可以用两种方式来运行这个程序,一种就是直接命令调用:$./junk.exe,另一种就是通过wine加载调用:$wine junk.exe.so。如无意外,这个程序会弹出三个windows风格的消息框,一个用机器的名义和你say "Howdy World!",第二个输出HelloWorld这个函数的地址,最后一个是这个函数中调用的消息框。

      这里说一下winegcc,它是winelib在gcc编译器上的一层封装,使其能编译出能给wine加载的二进制程序,用法和普通的gcc类似。而wineg++就是对g++编译器的封装,用法也和g++差不多。

Relate Posts:// 相关文章

也来谈谈云计算»
«IT业界准则:成就客户是生意根基

我要留言

10+1=