如何将 C++/CLI 结构数组编组到非托管 C++

发布于 2024-07-17 09:14:06 字数 444 浏览 3 评论 0原文

我正在寻找正确的语法来将结构数组传递给非托管 C++ dll。

我的 dll 导入是这样调用的

    #define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);

在我的客户端代码中,我

List<MyStruct^> list;
MyObject::_Validation(/* list*/);

知道 System::Runtime::InteropServices::Marshal 有很多有用的方法来执行此类操作,但我不确定使用哪个。

I'm searching for the correct syntax to pass a struct array to an unmanaged C++ dll.

my dll imports are called like this

    #define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);

In my client code I have

List<MyStruct^> list;
MyObject::_Validation(/* list*/);

I know System::Runtime::InteropServices::Marshal has a lot of useful methods for doing stuff like this but I'm not sure about which to use.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜未央樱花落 2024-07-24 09:14:06

使用 StructLayout.Sequential 创建非托管结构的托管版本(确保按相同顺序放置内容)。 然后,您应该能够像将其传递给任何托管函数一样传递它(例如,Validation(MyStruct[] pStructs)。

例如,假设我们的本机函数具有此原型:

extern "C" {

STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);

}

并且本机 MYSTRUCT 定义如下:

struct MYSTRUCT
{
    int a;
    int b;
    char c;
};

然后在 C# 中,定义该结构的托管版本,如下所示:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MYSTRUCT
{
    public int a;
    public int b;
    public byte c;
}

托管原型如下:

    [System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
    public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);

然后,您可以调用该函数,并向其传递 MYSTRUCT 结构数组,如下所示:

    static void Main(string[] args)
    {
        MYSTRUCT[] structs = new MYSTRUCT[5];

        for (int i = 0; i < structs.Length; i++)
        {
            structs[i].a = i;
            structs[i].b = i + structs.Length;
            structs[i].c = (byte)(60 + i);
        }

        NativeMethods.fnStructInteropTest(structs, structs.Length);

        Console.ReadLine();
    }

Create a managed version of the unmanaged struct using StructLayout.Sequential (make sure to put things in the same order). You should then be able to pass it like you'd pass it to any managed function (e.g., Validation(MyStruct[] pStructs).

For example, let's say our native function has this prototype:

extern "C" {

STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);

}

and the native MYSTRUCT is defined as follows:

struct MYSTRUCT
{
    int a;
    int b;
    char c;
};

Then in C#, you define a managed version of the struct as follows:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MYSTRUCT
{
    public int a;
    public int b;
    public byte c;
}

And the managed prototype as follows:

    [System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
    public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);

You can then call the function passing it an array of MYSTRUCT structs as follows:

    static void Main(string[] args)
    {
        MYSTRUCT[] structs = new MYSTRUCT[5];

        for (int i = 0; i < structs.Length; i++)
        {
            structs[i].a = i;
            structs[i].b = i + structs.Length;
            structs[i].c = (byte)(60 + i);
        }

        NativeMethods.fnStructInteropTest(structs, structs.Length);

        Console.ReadLine();
    }
爱给你人给你 2024-07-24 09:14:06

您可以使用 Marshall.StructureToPtr获取可以传递到本机 MyStruct* 数组中的 IntPtr。

但是,我不确定如何直接从列表中执行此操作。 我相信您需要将其转换为数组并使用 pin_ptr (以防止 GC 移动内存),然后再将其传递给本机代码。

You can use Marshall.StructureToPtr to get an IntPtr which could be passed into a native MyStruct* array.

However, I'm not sure how to do this from a List directly. I believe you need to convert this to an array and use a pin_ptr (to prevent the GC from moving your memory) prior to passing it to the native code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文