在Linux上使用Wine封装Windows dll

时间:2019-07-19 22:28:08

标签: wine

基本上,我想知道是否有一种方法可以使用Wine(可能是libwine?)为Windows .dll制作包装器.so。我在其中加载.dll,从中加载一些函数指针,然后像FFI一样使用Wine。 Wine似乎必须在内部执行此操作,并不断地从System V ABI和Windows来回调用。

具体来说,我有一个用于昂贵的科学数据记录设备的接口库,该设备通过UDP而不是直接与硬件进行通信。该API本身只有大约20个使用简单类型(int,doubles,double [])的函数,因此,如果确实有可能,手工制作一个包装器就没那么多了。

编辑: 我取得了部分进展,但没有解决方案。我读了一些书,发现了关于winegcc的知识。我知道libSDL具有相当简单的日志功能,所以我得到了它的Windows .dll并执行以下操作:

HINSTANCE sdl = LoadLibrary("SDL2.dll");
assert(sdl);

typedef void logf(const char* fmt, ...);
logf *log = (logf*)GetProcAddress(sdl, "SDL_Log");
assert(log);

log("Hello");

这很有效!它向控制台输出“ INFO:?? {”,因此可以正确检索函数指针,并且由于它完全可以打印任何内容,因此dll必须正确地回调libwine。我有点希望GetProcAddress()返回一个可以为我转换ABI的魔术蹦床,但事实并非如此吗?如果我使用内联汇编调用log函数以使用MS ABI传递参数,它仍然会执行相同的操作,因此我不确定下一步如何尝试。

1 个答案:

答案 0 :(得分:0)

啊!我好近发布解决方案需要花费几天的时间才能弄清楚。

我只需要在函数声明中添加“ WINAPI”限定符即可。如果它所做的只是设置调用约定,我不确定为什么我的程序集版本无法正常工作,但是无论如何。例如,以下代码使用Windows SDL2.dll在Linux上成功打开一个窗口。

HINSTANCE sdl = LoadLibrary("SDL2.dll");
assert(sdl);

WINAPI __typeof(SDL_Init)* init = GetProcAddress(sdl, "SDL_Init");
err = init(SDL_INIT_VIDEO);
assert(err == 0);

WINAPI __typeof(SDL_CreateWindow)* create_window = GetProcAddress(sdl, "SDL_CreateWindow");
SDL_Window* window = create_window("Drift", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, 0);
assert(window);

WINAPI __typeof(SDL_Delay)* delay = GetProcAddress(sdl, "SDL_Delay");
delay(3000);