Podczas próby udowodnienia kolegom, że można używać klas C++ z F #, wymyśliłem następujący dowód koncepcji. Pierwszy fragment to kod podany dla wyzwania, a poniższy fragment kodu jest moją implementacją w języku F #.Możliwe F # Interactive PInvoke bug
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)
Gdy debugowanie w Visual Studio lub działać jako samodzielny program, to działa przewidywalnie: TrivialFoo.Get
zwraca wartość bar
i TrivialFoo.Set
przypisuje do niego. Po uruchomieniu z F # Interactive jednak TrivialFoo.Set
nie ustawi pola. Podejrzewam, że może to mieć coś wspólnego z dostępem do zarządzanej pamięci z niezarządzanego kodu, ale to nie wyjaśnia, dlaczego tak się dzieje tylko przy użyciu F # Interactive. Czy ktoś wie, co tu się dzieje?
Cóż, to nie jest sposób na współdziałanie w każdym razie. Deklaracja POD struct z funkcjami non + piąta. Domyślam się, że kod zawodzi, ponieważ struktura jest uważana za paramatyczną metodę, ale w każdym razie wszystko jest w porządku. Nie tak postępujesz w klasach. –
Innym typowym problemem może być to, że biblioteka DLL nie jest w% PATH% podczas używania FSI zamiast .exe. – weismat
Zwłaszcza, że domyślnie FSI kopiuje kopie złożeń, więc twój kod może być uruchomiony z tymczasowego folderu gdzieś. – marklam