(一):介绍


出于某些原因,你可能会发现你想要和使用Windows DLL一样使用你的Linux库.对于这有一些原因例如以下:

  • 你正在支持一个使用多个第三方库的大应用.该项目在Linux中是可用的,可是你还没有准备直接链接到他作为一个Linux共享库.

  • 有一个定义好的可用的接口,而且有许多用于接口的解决的方法.

  • 你仅仅有一个二进制Windows应用,他能够通过插件扩展,比如文本编辑器或IDE.

处理这些问题的过程是很easy的.你须要编写一个spec文件,该文件以同样的格式描写叙述库接口作为一个DLL.当然,你可能希望为库编写一个小的封装.你组合他们形成一个Wine内置的链接到Linux库的DLL.然后你在wine配置中改动theDllOverrides来确保这个新内置的DLL被调用,而不是不论什么的Windows版本号.

在这个小节中,我们将会看到两个样例程序.第一个样例是很easy的,而且在”baby steps”中引入主题.都二个样例是在Wine中ODBC的接口代理.我们将要位ODBC样例引用的文件位于Wine源代码的dlls/odbc32文件夹中.

第一个样例是基于一个情况(比如,函数的名称已经被改变了来保护无辜的函数).大量的Windows应用包括链接到第三方DLL的DLL.出于一些原因,第三方DLL在Wine中执行不是很好.然后,第三方库在Linux环境中也是可用的.方便的是,DLL和Linux共享库仅仅有一小部分功能,而且应用仅仅用使用当中的一个.

特别的,应用调用一个函数:

signed short WINAPI MyWinFunc (unsigned short a, void *b, void *c,unsigned long *d, void *e, int f, char g, unsigned char *h);

linux库包括一个相应的函数:

signed short MyLinuxFunc (unsigned short a, void *b, void *c,unsigned short *d, void *e, char g, unsigned char *h);

(二):编写spec文件


通过编写spec文件開始.这个文件描写叙述接口,好像他是DLL一样.

在这个简单的样例中,我们想要一个Wine内置的DLL和MyWin DLL相相应.spec文件是MyWin.dll.spec,而且看上去像这:

#
# File: MyWin.dll.spec
#
# some sort of copyright
#
# Wine spec file for the MyWin.dll built-in library (a minimal wrapper around the
# linux library libMyLinux)
#
# For further details of wine spec files see the Winelib documentation at
# www.winehq.org 2 stdcall MyWinFunc (long ptr ptr ptr ptr long long ptr) MyProxyWinFunc # End of file

注意,參数被标记成了long,即使他们比那个要小.通过这个样例,我们将直接链接到Linux共享库,而通过ODBC这个样例,我们将动态载入Linux共享库.

在ODBC样例中,你能够在文件odbc32.spec中看到这些.

(三):编写一个封装


首先,我们将要看一个简单的样例.这个样例基本的问题就是长处不同的參数列表.f參数不必传递给Linux函数,而且d參数理论上须要从unsigned long *unsigned short *之间转换.这么做是为了确保高位的返回值被正确设置.也不像ODBC样例一样,我们将要直接链接到Linux的共享库上.

/*
* File: MyWin.c
*
* Copyright (c) The copyright holder.
*
* Basic Wine wrapper for the Linux 3rd party library so that it can be
* used by the application
*
* Currently this file makes no attempt to be a full wrapper for the 3rd
* party library; it only exports enough for our own use.
*
* Note that this is a Unix file; please don't go converting it to DOS format
* (e.g. converting line feeds to Carriage return/Line feed).
*
* This file should be built in a Wine environment as a Winelib library,
* linked to the Linux 3rd party libraries (currently libxxxx.so and
* libyyyy.so)
*/ #include <3rd party linux header>
#include <windef.h> /* Part of the Wine header files */ /* This declaration is as defined in the spec file. It is deliberately not
* specified in terms of 3rd party types since we are messing about here
* between two operating systems (making it look like a Windows thing when
* actually it is a Linux thing). In this way the compiler will point out any
* inconsistencies.
* For example the fourth argument needs care
*/
signed short WINAPI MyProxyWinFunc (unsigned short a, void *b, void *c,unsigned long *d, void *e, int f, char g, unsigned char *h)
{
unsigned short d1;
signed short ret; d1 = (unsigned short) *d;
ret = 3rd party linux function (a, b, c, &d1, e, g, h);
*d = d1; return ret;
} /* End of file */

对于一个更广泛的情况,我们能够使用ODBC样例.这个被实现位一个头文件(proxyodbc.h)和一个C源代码文件(proxyodbc.c).尽管文件很长,可是在结构上很easy.

DllMain函数用于初始化DLL.在过程附加事件中,函数动态链接到期望的Linux ODBC库中(由于有若干个可用的),而且构建一系列的函数指针.在过程解附加事件中,他解除链接.

然后每个函数通过在初始化过程中设置的函数指针调用适当的Linux函数.

(四):构建


那么我们怎样构建一个Wine内置的DLL呢?

最简单的方法就是使winemaker来为我们做这些复杂的工作.举个简单样例,我们有两个源代码文件(封装和spec文件).我们也有第三方头文件和库文件.

将这两个源文件放到一个合适的文件夹中,然后使用winemaker来创建构建框架,包括配置脚本,makefile等等.你可能希望使用以下的选项:

  • --nosource-fix (须要winemaker的版本号为0.5或更新)来确保两个文件未被改动(假设使用了一个较低版本号,使这两个文件仅仅读,而且忽略不能改动他们的投诉).

  • --dll --single-target MyWin --nomfc 来指定目标

  • --DMightNeedSomething -I3rd_party_include -L3rd_party_lib -lxxxx -lyyyy 这些头文件的位置等

在执行winemaker之后,我能够仅仅在定义之前编辑Makefile,向当中加入一行CEXTRA = -Wall.

然后就是简单的执行confugure和make就可以.

(五):安装


那么我们怎样安装代理,而且确保每个事物都连接正确呢?

在这个事情上有很大的灵活性,所以须要遵循的不是唯一可行的选项.

确保Linux共享对象放到了Linux系统能够找到的地方.这就意味着他应该被放在在/etc/ld.so.conf文件里提及的文件夹中的一个中或者是在LD_LIBRARY_PATH指定的路径以下.假设你能从Linux程序中链接到他,应该也是能够的.

讲代理共享对象(MyWin.dll.so)放到同样的位置作为内置DLL的其它部分.确保WINEDLLPATH包括有代理共享对象的文件夹.

假设你既有Windows DLL也有一个Linux DLL/代理对,那么你必须确保有正确的一个得到调用.最简单的方法就是重命名Windows版本号,使他不被检測到.你能够使用winecfg设置一个DLL重写,这样内置版本号就会被使用.

一旦你这样做了,你就应该成功的使用Linux共享对象了.假设你有问题,然后在执行wine之前设置 WINEDEBUG=+module环境变量来查看真正发生了什么.

(六):转换文件名称


假设你想要转换传入的DOS格式的文件名称称到他们等效的Unix格式.当然,在微软的Windows API中没有合适的函数,可是wine提供了一个用于这个工作的函数,而且从kernel32 DLL的拷贝中导出的.这个函数就是wine_get_unix_file_name(定义在winbase.h)中.

(八):构建WineLib DLL的更多相关文章

  1. 检查.net dll构建的目标平台是any cpu、x86、x64

    有时候,需要检查构建的dll是否针对正确的平台 可以使用CorFlags.exe(它是.NET Framework SDK的一部分)从dll中查找此信息.运行CorFlags.exe将产生以下输出: ...

  2. Linux From Scratch(从零开始构建Linux系统,简称LFS)- Version 7.7(二)

    七. 构建临时系统 1. 通用编译指南 a. 确认是否正确设置了 LFS 环境变量 echo $LFS b. 假定你已经正确地设置了宿主系统的符号链接: 1)shell 使用的是 bash. 2)sh ...

  3. VS2010 C++环境下DLL和LIB文件目录及名称修改

    VS2010 C++环境下DLL和LIB文件目录及名称修改 转自:http://blog.csdn.net/archielau/article/details/8507581 DLL工程,Debug版 ...

  4. LabVIEW如何方便地调用DLL文件

    转自:http://bbs.elecfans.com/jishu_469502_1_1.html   LabVIEW调用DLL文件 LabVIEW支持通过调用DLL文件的方式与其它编程语言混合使用.比 ...

  5. 动态链接库 —— Dll 基础

    1. DLL 的初识 在 windows 中,动态链接库是不可缺少的一部分,windows 应用程序程序接口提供的所有函数都包含在 DLL 中,其中有三个非常重要的系统 DLL 文件,分别为 Kern ...

  6. Linux From Scratch(从零开始构建Linux系统,简称LFS)(二)

    七. 构建临时系统 1. 通用编译指南 a. 确认是否正确设置了 LFS 环境变量 echo $LFS b. 假定你已经正确地设置了宿主系统需求和符号链接 c. 对于每个软件包: (1). 确保解压软 ...

  7. [译] 优化 WEBPACK 以更快地构建 REACT

    原文地址:OPTIMIZING WEBPACK FOR FASTER REACT BUILDS 原文作者:Jonathan Rowny 译文出自:掘金翻译计划 本文永久链接:https://githu ...

  8. 精通C#(第6版)

    <精通C#(第6版)> 基本信息 原书名:Pro C# 5.0 and the .NET 4.5 framework,sixth edition 作者: (美)Andrew Troelse ...

  9. C++与Lua交互(四)

    引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...

随机推荐

  1. curl保存图片

    $url = 'http://p1.qhimg.com/t013dfc89f8a039122c.jpg?size=690x460'; function http_get_data($url) { $c ...

  2. LibreOJ2095 - 「CQOI2015」选数

    Portal Description 给出\(n,k,L,R(\leq10^9)\),求从\([L,R]\)中选出\(n\)个可相同有顺序的数使得其gcd为\(k\)的方案数. Solution 记\ ...

  3. 解决vue项目route使用history模式,tomcat部署刷新url 404问题

    在webapps/项目名 创建WEB-INF ,创建web.xml文件 文件内容如下: <?xml version="1.0" encoding="UTF-8&qu ...

  4. codeforces 900D 数论+组合+容斥原理

    问有多少个这样的数字序列 所有数的GCD等于x 并且 所有数的和等于y 题解: 非常难有思路啊 看题解后过的. 考虑序列GCD为x的倍数 即GCD = n*x 和当然都为y 这个条件不要忘了 这样我们 ...

  5. Linux System Programming 学习笔记(七) 线程

    1. Threading is the creation and management of multiple units of execution within a single process 二 ...

  6. Spring Boot的web开发&静态资源配置方式

    Web开发的自动配置类:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration 1.1. 自动配置的ViewResolve ...

  7. Linux Malloc分析-从用户空间到内核空间【转】

    转自:http://blog.csdn.net/ordeder/article/details/41654509 版权声明:本文为博主(http://blog.csdn.net/ordeder)原创文 ...

  8. unity3d的模型规范

    1.不能存在单独的点和面,重复的面和点,不能被玩家所看到的模型也不必制作. 2.贴图要保证始终是2的倍数,但不必为正方形. 3.移动平台,如IP4,应该每个模型一般不超过300-1500个面,同屏不应 ...

  9. 关于微信浏览器不支持offset()的兼容性处理

    问题的背景: 在手机触屏版中,当页面向上滑动的时候,导航条可以固定在顶部,通过判断offset().top的值来实现这个功能,其他的浏览器都可以,只有微信浏览器中出现问题(向上滑动的时候,导航条就会直 ...

  10. python装饰器的深度探究

    1.讲装饰器一般讲到这种代码就可以了,但这篇博客会介绍更多: def deco(func): def wrapper(): print("start") func() #调用函数 ...