gpt4 book ai didi

c++ - F#:使用自定义类型参数调用 native 函数

转载 作者:行者123 更新时间:2023-12-01 14:47:09 26 4
gpt4 key购买 nike

我正在从 F# 调用 native DLL。事实证明,对于不带参数或仅带基本类型的函数来说,这非常简单,但我很难让我的代码以其他方式工作。
C++代码是:

struct CatDef
{
uint8_t cat;
uint8_t arrogance;

CatDef() : cat(0), arrogance(0) {}
};

struct HomeInfo
{
enum { MAX_CATDEF = 5 };
enum {
LONE_CAT = 0x01,
};
CatDef cd[MAX_CATDEF];
uint8_t notoriety;
uint8_t etc;

HomeInfo()
: notoriety(0), etc(0)
{
memset(cd, 0, sizeof(cd));
}

size_t howBig() const
{
size_t hb = 0;
for (; hb < MAX_CATDEF; ++hb)
if (!cd[hb].cat)
break;
return hb;
}
};

struct HomeQuery
{
char addr[ADDR_LENGTH]; // ADDR_LENGTH is 1024
char verifiedAddr[ADDR_LENGTH];
HomeInfo homeData;
unsigned int id;
Status st; // Status is an enum

HomeQuery()
: homeData()
, id(0)
, st(Unprocessed)
{
memset(addr, 0, sizeof(addr));
memset(verifiedAddr, 0, sizeof(verifiedAddr));
}
};

__declspec(dllexport) bool GetHomeInfo(
HomeQuery* queries, size_t qCount, void (*callback)(HomeQuery*, size_t) = 0);
到目前为止,我有这个用于 F#:
[<Struct>]
type CatDef =
[<DefaultValue>]
val mutable cat : uint8
[<DefaultValue>]
val mutable arrogance : uint8

[<Struct>]
type HomeInfo =
[<DefaultValue; MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)>]
val mutable cd : CatDef array
[<DefaultValue>]
val mutable notoriety : uint8
[<DefaultValue>]
val mutable etc : uint8

[<Struct>]
type HomeQuery =
[<DefaultValue; MarshalAs(UnmanagedType.LPStr, SizeConst = 1024)>]
val mutable addr : string
[<DefaultValue; MarshalAs(UnmanagedType.LPStr, SizeConst = 1024)>]
val mutable verifiedAddr : string
[<DefaultValue>]
val mutable homeData : HomeInfo
[<DefaultValue>]
val mutable id : uint32
[<DefaultValue>]
val mutable st : int

type HomeQueryCallback = delegate of (HomeQuery array * uint) -> unit

module private Wrapper =
[<DllImport(
"Homes.dll",
EntryPoint = "?GetHomeInfo@People@@NA_WBYUHomeQuery@1@IP6AX0I@Z@Z",
CallingConvention = CallingConvention.Cdecl)>]
extern bool GetHomeInfo(HomeQuery[] queries, uint qCount, HomeQueryCallback callback)

[<RequireQualifiedAccess>]
module HomeLib =
let getHomeInfo queries = Wrapper.GetHomeInfo (queries, uint queries.Length, null)
关于类型编码的规则,我引用了 https://docs.microsoft.com/en-us/dotnet/standard/native-interop/type-marshaling#default-rules-for-marshaling-common-types .
当我打电话时 HomeLib.getHomeInfo并进入 native 库(Homes.dll),我看到 HomeQuery中第一个(也是唯一一个)项目的字段。数组包含乱码信息。 ( qCountcallback 未损坏,并包含预期值。)如您所见,我尝试添加 MarshalAs归因于一些领域,但这并没有产生任何积极影响。也没有用 [<StructLayout(LayoutKind.Sequential)>] 装饰任何类型.

最佳答案

没关系,我搞定了。
对于可能关心的任何人,我的 F# 代码只进行了一些更改:

  • 我改了UnmanagedType.LPStrUnmanagedType.ByValTStr
  • extern函数声明,我装饰HomeQuery[] queries[<In; Out>] (即 [<In; Out>]HomeQuery[] queries )。

  • 就这样。

    关于c++ - F#:使用自定义类型参数调用 native 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63276765/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com