我正在尝试将一个结构从 C 编组到 C#,不知道从哪里开始

发布于 2024-10-08 11:25:35 字数 988 浏览 0 评论 0原文

我的 C++ 结构如下

 /* this structure contains the xfoil output parameters vs angle of attack */
    typedef struct xfoil_outputdata_struct
    {
     double *pAlfa;
     double *pCL;
     double *pCM;
     double *pCDi;
     double *pCDo;
     double *pCPmax;
     long nEntries;
    } XFOIL_OUTPUT_DATA;

    /* Here are the function prototypes for XFoil */
    __declspec(dllexport) XFOIL_OUTPUT_DATA *xfoilResults(); /* get output from xfoil */

我使用 XFoilResults 将此结构拉回 C#

我的 DLL 导入语句如下:

 [DllImport("xfoilapi.dll")]
        public static extern void xfoilResults();

这是正确的吗?我无法控制 C++ 代码。我只需要能够将结构拉入 C# 中。到目前为止,我拥有的 C# 结构如下:

[StructLayout(LayoutKind.Sequential)]
    public  struct xfoilResults
    {
     IntPtr pAlfa;
        IntPtr pCL;
        IntPtr pCM;
        IntPtr pCDi;
        IntPtr pCDo;
        IntPtr pCPmax;
     long nEntries;
    }

如何使用 C++ 代码中的数据填充此 C# 结构?

My struct in C++ is the following

 /* this structure contains the xfoil output parameters vs angle of attack */
    typedef struct xfoil_outputdata_struct
    {
     double *pAlfa;
     double *pCL;
     double *pCM;
     double *pCDi;
     double *pCDo;
     double *pCPmax;
     long nEntries;
    } XFOIL_OUTPUT_DATA;

    /* Here are the function prototypes for XFoil */
    __declspec(dllexport) XFOIL_OUTPUT_DATA *xfoilResults(); /* get output from xfoil */

I use XFoilResults to pull this structure back into C#

My DLL Imports statement is the following:

 [DllImport("xfoilapi.dll")]
        public static extern void xfoilResults();

Is this correct? I have no control over the C++ code. I just need to be able to pull the struct into C#. The C# struct I have so far is the following

[StructLayout(LayoutKind.Sequential)]
    public  struct xfoilResults
    {
     IntPtr pAlfa;
        IntPtr pCL;
        IntPtr pCM;
        IntPtr pCDi;
        IntPtr pCDo;
        IntPtr pCPmax;
     long nEntries;
    }

How can I populate this C# structure with the data from the C++ code?

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

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

发布评论

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

评论(2

虚拟世界 2024-10-15 11:25:35

StructLayout 必须位于类上。

这应该可以解决问题:

[DllImport("xfoilapi.dll")]
public static extern IntPtr GetXfoilResults();

[StructLayout(LayoutKind.Sequential)]
public class XfoilResults
{
    IntPtr pAlfa;
    IntPtr pCL;
    IntPtr pCM;
    IntPtr pCDi;
    IntPtr pCDo;
    IntPtr pCPmax;
    int nEntries; // thanks to guys for reminding me long is 4 bytes
}

XfoilResults xf  ==  new XfoilResults();
Marshal.PtrToStructure(GetXfoilResults(), xf);

StructLayout must be on a class.

This should do the trick:

[DllImport("xfoilapi.dll")]
public static extern IntPtr GetXfoilResults();

[StructLayout(LayoutKind.Sequential)]
public class XfoilResults
{
    IntPtr pAlfa;
    IntPtr pCL;
    IntPtr pCM;
    IntPtr pCDi;
    IntPtr pCDo;
    IntPtr pCPmax;
    int nEntries; // thanks to guys for reminding me long is 4 bytes
}

XfoilResults xf  ==  new XfoilResults();
Marshal.PtrToStructure(GetXfoilResults(), xf);
别挽留 2024-10-15 11:25:35

首先,导入函数的返回类型应为 IntPtr[MarshalAs(UnmanagementType.LPStruct)] xfoilResults_t

第二个重要注意事项是,如果 xfoilResults() 正在该结构中分配和填充数据,则应该在某个地方有第二个函数来清理该内存。您还必须导入它 - 并根据需要调用它,否则最终会出现内存泄漏。

如果您要手动封送(即导入返回 IntPtr),您应该能够使用

IntPtr retval = xfoilResults();
var results = (xfoilResults_t)Marshal.PtrToStructure(
                                         retVal, 
                                         typeof(xfoilResults_t));

//Do the following for each IntPtr field
double[] pCL = new double[results.nEntries];
Marshal.Copy(results.pCL, pCL, 0, results.nEntries);

//Don't forget to call whichever function is cleaning up the unmanaged memory.

Firstly, the return type of your imported function should be either IntPtr or [MarshalAs(UnmanagedType.LPStruct)] xfoilResults_t.

A second important note is that, if xfoilResults() is allocating and populating the data in that struct, there should somewhere be a second function to clean up that memory. You must also import that - and call it as necessary, or you will end up with memory leaks.

If you're going to marshal this manually (ie, the import returns an IntPtr), You should be able to use

IntPtr retval = xfoilResults();
var results = (xfoilResults_t)Marshal.PtrToStructure(
                                         retVal, 
                                         typeof(xfoilResults_t));

//Do the following for each IntPtr field
double[] pCL = new double[results.nEntries];
Marshal.Copy(results.pCL, pCL, 0, results.nEntries);

//Don't forget to call whichever function is cleaning up the unmanaged memory.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文