Utilizzando Windows DLL da Linux

Dobbiamo interfacciare con l’app di terze parti, ma la società dietro l’app non rivela il protocollo dei messaggi e fornisce solo la DLL di Windows a cui interfacciarsi.

La nostra applicazione è basata su Linux, quindi non posso comunicare direttamente con la DLL. Non sono riuscito a trovare alcuna soluzione esistente, quindi sto pensando di scrivere un bridge basato su socket tra Linux e Windows, tuttavia sono sicuro che non è un problema così unico e qualcuno avrebbe dovuto farlo prima.

Sei a conoscenza di qualsiasi soluzione che permetta di chiamare le funzioni di Windows DDL dall’app C su Linux? Può utilizzare Wine o un PC Windows separato, non importa.

Molte grazie in anticipo.

Qualsiasi soluzione avrà bisogno di un layer “remoting” basato su TCP / IP tra la DLL che gira in un ambiente “windows-like” e la tua app linux.

Avrai bisogno di scrivere una semplice app per PC per esporre le funzioni DLL, usando un protocollo homebrew o forse i protocolli XML-RPC, SOAP o JSON. RemObjects SDK potrebbe aiutarti – ma potrebbe essere eccessivo.

Rimanerei con un PC “reale” o virtualizzato. Se si utilizza Wine, è improbabile che gli sviluppatori DLL offrano alcun supporto.

È inoltre improbabile che MONO sia di aiuto, poiché la DLL probabilmente NON è un assembly .NET.

Prendi uno sniffer e impara il protocollo. È quello che sto facendo.

Sebbene questa domanda sia piuttosto vecchia, l’argomento apparentemente non ha perso la sua rilevanza. Se puoi usare o stai usando Python … ecco la mia soluzione.

Ho scritto un piccolo modulo Python per chiamare Windows DLL da Python su Linux. È basato su IPC tra un normale processo Linux / Unix Python e un processo Python basato sul vino. Poiché ne ho avuto bisogno in troppi casi d’uso / scenari diversi, l’ho progettato come una sostituzione drop-in del modulo “generico”, che fa automaticamente la maggior parte degli impianti idraulici necessari in background.

Esempio: supponiamo di essere in Python su Linux, di aver installato Wine e di voler chiamare msvcrt.dll (la libreria di runtime Microsoft C). Puoi fare quanto segue:

 import zugbruecke as 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)) 

Codice sorgente (LGPL) , pacchetto PyPI e documentazione .

È ancora un po ‘ruvido attorno ai bordi (cioè alfa e insicuro), ma gestisce la maggior parte dei tipi di parametri (inclusi i puntatori).

A volte è meglio scegliere un piccolo venditore su un grande fornitore perché le dimensioni della tua attività ti daranno più peso. Lo abbiamo sicuramente trovato con i produttori di motori AV.

Se siete sufficientemente importanti per loro, dovrebbero fornire un protocollo documentato, supportato, una build Linux della libreria o il codice sorgente alla libreria.

Altrimenti dovrai eseguire una finestra di Windows nel ciclo usando RPC come altri hanno notato, il che potrebbe essere molto scomodo, specialmente se tutto il resto dell’infrastruttura esegue Linux.

Il venditore supporterà l’utilizzo della propria libreria all’interno di una VM Windows? Se le prestazioni non sono critiche, potresti essere in grado di farlo.

Chiamare le funzioni della DLL è ovviamente solo la punta dell’iceberg. Cosa succede se la DLL chiama Win32, quindi avresti un problema di collegamento piuttosto massiccio. Immagino che Wine potrebbe aiutarti, non sono sicuro che forniscano una soluzione.

IMO, la soluzione migliore è usare i socket. L’ho fatto in precedenza e funziona come un fascino.

Sono passati alcuni anni da quando è stata posta la domanda, ma ecco un altro approccio. Utilizzare objdump -d per disassemblare la DLL. È ansible ottenere spazzatura pura, non adulterata o piena di chiamate Windows o entrambe. Le funzioni sono spesso delimitate da una serie di istruzioni push e terminano con un’istruzione ret .

Non l’ho fatto, ma potresti essere in grado di creare un wrapper usando MONO.