При попытке доказать коллеге, что можно использовать классы С++ из F #, я придумал следующее доказательство концепции. Первый фрагмент кода - это код, который он предоставил для вызова, а фрагмент кода ниже - моя реализация в F #.
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)
При отладке в Visual Studio или запуске в качестве автономной программы это работает предсказуемо: TrivialFoo.Get
возвращает значение bar
и TrivialFoo.Set
. Однако, если вы запускаете F # Interactive, TrivialFoo.Set
не будет устанавливать это поле. Я подозреваю, что это может иметь какое-то отношение к доступу к управляемой памяти из неуправляемого кода, но это не объясняет, почему это происходит только при использовании F # Interactive. Кто-нибудь знает, что здесь происходит?