Durante il tentativo di dimostrare a un collega che è possibile utilizzare classi C++ da F #, ho trovato la seguente dimostrazione di concetto. Il primo frammento è il codice che ha fornito per la sfida e il frammento di codice seguente è la mia implementazione in F #.Possibile errore PInvoke F # interattivo
namespace testapp {
struct trivial_foo {
int bar;
__declspec(dllexport) void set(int n) { bar = n; }
__declspec(dllexport) int get() { return bar; }
}
}
open System.Runtime.InteropServices
type TrivialFoo =
struct
val bar: int
new(_bar: int) = { bar = _bar }
end
[<DllImport("Win32Project2.dll", EntryPoint="[email protected][email protected]@@QAEHXZ", CallingConvention = CallingConvention.ThisCall)>]
extern int trivial_foo_get(TrivialFoo& trivial_foo)
[<DllImport("Win32Project2.dll", EntryPoint="[email protected][email protected]@@[email protected]", CallingConvention = CallingConvention.ThisCall)>]
extern void trivial_foo_set(TrivialFoo& trivial_foo, int bar)
type TrivialFoo with
member this.Get() = trivial_foo_get(&this)
member this.Set(bar) = trivial_foo_set(&this, bar)
Quando il debug in Visual Studio o eseguire come programma autonomo, questo funziona prevedibile: TrivialFoo.Get
restituisce il valore di bar
e TrivialFoo.Set
assegna ad esso. Se eseguito da F # Interactive, tuttavia, TrivialFoo.Set
non imposterà il campo. Sospetto che possa avere qualcosa a che fare con l'accesso alla memoria gestita dal codice non gestito, ma questo non spiega perché accade solo quando si usa F # Interactive. Qualcuno sa cosa sta succedendo qui?
Bene, questo non è il modo di fare interop lo stesso. Dichiarare una struttura POD con funzioni non + imember. Immagino che il tuo codice stia fallendo perché la struttura è considerata un parametro in te, ma in ogni caso è tutto sbagliato. Questo non è il modo in cui si interpola con le classi. –
Un altro problema tipico potrebbe essere che la DLL non è in% PATH% quando si utilizza FSI anziché .exe. – weismat
Soprattutto perché l'ombra FSI copia gli assembly per impostazione predefinita, quindi il codice potrebbe essere in esecuzione da una cartella temporanea da qualche parte. – marklam