(八):构建WineLib DLL

简介: 版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/50704597 (一):介绍出于某些原因,你可能会发现你想要和使用Windows DLL一样使用你的Linux库.
版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/50704597

(一):介绍


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

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

  • 有一个定义好的可用的接口,并且有很多用于接口的解决办法.

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

处理这些问题的过程是非常简单的.你需要编写一个spec文件,该文件以相同的格式描述库接口作为一个DLL.当然,你可能希望为库编写一个小的封装.你组合他们形成一个Wine内置的链接到Linux库的DLL.然后你在wine配置中修改theDllOverrides来确保这个新内置的DLL被调用,而不是任何的Windows版本.

在这个小节中,我们将会看到两个例子程序.第一个例子是非常简单的,并且在”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).虽然文件非常长,但是在结构上非常简单.

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)中.

目录
相关文章
|
28天前
|
XML C# 数据格式
掌握了在Windows平台上查看DLL依赖的方法
掌握了在Windows平台上查看DLL依赖的方法
173 4
|
JavaScript
Electron如何调用.dll文件
Electron如何调用.dll文件
1060 0
Electron如何调用.dll文件
|
算法 C++
解决方案-Visual Studio生成库(DLL&LIB)以及如何调用
解决方案-Visual Studio生成库(DLL&LIB)以及如何调用
483 0
|
开发者 C++ Windows
Windows平台如何查看一个dll依赖的其他dll
好多开发者在做windows开发的时候,容易遇到dll依赖的问题,VS自带一个小工具dumpbin, 这个工具挺好用,可以查看dll相关依赖库,还可以看dll导出接口。
265 0
|
C# 图形学 C++
Unity与 DLL文件 ☀️| 怎样使用 C# 类库 生成一个DLL文件 并 调用!
📢前言 🎬生成DLL文件 🎥使用 C#类库 将Unity中的脚本打包成 DLL文件 并调用 🏳️‍🌈第一步:打开Visual Studio之后,新建一个项目 🏳️‍🌈第二步:选择类库(.NET Framework),改个名字,选择一个位置路径 🏳️‍🌈第三步:然后在创建的脚本中简单写一点代码,如下所示 🏳️‍🌈第四步:然后在解决方案资源管理器右键这个脚本 -> 添加 -> 引用 🏳️‍🌈第五步:然后点击浏览,找到Unity安装路径 -> Editor -> Data -> Managed 下的这两个DLL 文件,点击添加!
Unity与 DLL文件 ☀️| 怎样使用 C# 类库 生成一个DLL文件 并 调用!
|
程序员 编译器 Linux
Unity与 DLL文件 ☀️| 什么是DLL✨?
📣前言 在之前的文章有介绍过so文件,那本篇文章就来介绍一些DLL文件吧! 提起DLL文件,大家肯定不会陌生,就算自己没编写生成过DLL文件,那也一定见过! Windows系统打开电脑C盘的System文件夹,往下一拉就会发现有超级多的带有.dll后缀的文件! 那DLL文件到底是个怎样的存在呢?本篇文章就来好好研究一下这个DLL文件究竟是个啥!
Unity与 DLL文件 ☀️| 什么是DLL✨?
|
C# .NET 开发框架
C# 版dll 程序集合并工具
原文:C# 版dll 程序集合并工具 C# 版dll 程序集合并工具      最近要开发一个控件给同事用,开发中会引用一些第三方DLL,这样交给用户很不方便,希望的效果是直接交付一个DLL文件。网上找了一些资料。
1159 0
|
存储 C# C++
VS2005环境下的DLL应用
VS2005环境下的DLL应用 作者:一点一滴的Beer http://beer.cnblogs.com/     以前写过一篇题为《VC++的DLL应用(含Demo演示)》的文章,当时是刚开始接触DLL,而且所讲到的一些DLL的应用都是比较浅层次的数据传递,基本不具备很强的实用性,而且所选用的开发环境是VC6.0,这次因为做做WinCE开发的过程中需要用到这个技术,所以进行了比较深入的研究,而且此次用的是VS2005开发环境,对比VC6.0的一些操作略有不同,所以重新进行了整理。
1172 0