25

We need to interface to 3rd party app, but company behind the app doesn't disclose message protocol and provides only Windows DLL to interface to.

Our application is Linux-based so I cannot directly communicate with DLL. I couldn't find any existing solution so I'm considering writing socket-based bridge between Linux and Windows, however I'm sure it is not such a unique problem and somebody should have done it before.

Are you aware of any solution that allows to call Windows DDL functions from C app on Linux? It can use Wine or separate Windows PC - doesn't matter.

Many thanks in advance.

qrdl
  • 34,062
  • 14
  • 56
  • 86

6 Answers6

11

I wrote a small Python module for calling into Windows DLLs from Python on Linux. It is based on IPC between a regular Linux/Unix Python process and a Wine-based Python process. Because I have needed it in too many different use-cases / scenarios myself, I designed it as a "generic" ctypes module drop-in replacement, which does most of the required plumbing automatically in the background.

Example: Assume you're in Python on Linux, you have Wine installed, and you want to call into msvcrt.dll (the Microsoft C runtime library). You can do the following:

from zugbruecke import ctypes
dll_pow = ctypes.cdll.msvcrt.pow
dll_pow.argtypes = (ctypes.c_double, ctypes.c_double)
dll_pow.restype = ctypes.c_double
print('You should expect "1024.0" to show up here: "%.1f".' % dll_pow(2.0, 10.0))

Source code (LGPL), PyPI package & documentation.

It's still a bit rough around the edges (i.e. alpha and insecure), but it does handle most types of parameters (including pointers).

s-m-e
  • 3,433
  • 2
  • 34
  • 71
10

Any solution is going to need a TCP/IP-based "remoting" layer between the DLL which is running in a "windows-like" environment, and your linux app.

You'll need to write a simple PC app to expose the DLL functions, either using a homebrew protocol, or maybe XML-RPC, SOAP or JSON protocols. The RemObjects SDK might help you - but could be overkill.

I'd stick with a 'real' or virtualized PC. If you use Wine, the DLL developers are unlikely to offer any support.

MONO is also unlikely to be any help, because your DLL is probably NOT a .NET assembly.

Roddy
  • 66,617
  • 42
  • 165
  • 277
4

Sometimes it is better to pick a small vendor over a large vendor because the size of your business will give you more weight for them. We have certainly found this with AV engine vendors.

If you are sufficiently important to them, they should provide either a documented, supported protocol, a Linux build of the library, or the source code to the library.

Otherwise you'll have to run a Windows box in the loop using RPC as others have noted, which is likely to be very inconvenient, especially if the whole of the rest of your infrastructure runs Linux.

Will the vendor support the use of their library within a Windows VM? If performance is not critical, you might be able to do that.

MarkR
  • 62,604
  • 14
  • 116
  • 151
2

Calling the DLL's functions themselves is of course only the tip of the iceberg. What if the DLL calls Win32, then you'd have a rather massive linking problem. I guess Wine could help you out there, not sure if they provide a solution.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

IMO, the best bet is to use Sockets. I have done this previously and it works like a charm.

Aamir
  • 14,882
  • 6
  • 45
  • 69
0

An alternate approach is to use objdump -d to disassemble the DLL, and then recompile/reassemble it. Don't expect to be able to recompile the code unedited. You might get pure, unadulterated rubbish, or code full of Windows calls, or both. Look for individual functions. Functions are often delimited by a series of push instructions and end with a ret instruction.

casualcoder
  • 4,770
  • 6
  • 29
  • 35
  • 2
    Disassembling the DLL can be helpful if your goal is to reverse-engineer its behavior. However, don't expect to be able to disassemble a Windows DLL and re-assemble it as a functional Linux shared object. – minexew Apr 09 '21 at 08:32