c# - 将结构从 c# 传递到 C dll

标签 c# c pinvoke structure

我正在尝试学习足够多的 C#,以便我可以通过引用 C DLL 来传递结构;但它永远不会到达“cFunction”。正如您在 cFunction 中看到的,我明确地将 streamSubset 值设置为 44;但回到 c# 部分,它不会返回“44”。 这是 C 代码:

typedef struct s_mPlot
{
    double      price[100];
    int         streamSubset;
} mPlot;

extern "C" __declspec( dllexport )  
void cFunction(mPlot *Mplot){
    Mplot->streamSubset = 44;}

//这是c#代码

 using System;
    using Vibe.Function;
    using System.Runtime.InteropServices;
    [StructLayout(LayoutKind.Sequential)]
    public class MPLOT 
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
        public double []    price;
        public int          streamSubset;
     } 

namespace Vibe.Indicator{
public class myIdx : IndicatorObject {

    [DllImport("C:\\Users\\joe\\mcDll.dll", CharSet = CharSet.Auto)]
    public static extern void cFunction(
    [In, MarshalAs(UnmanagedType.LPStruct)]  MPLOT  mPlot );
    public myIdx(object _ctx):base(_ctx){}
    private IPlotObject plot1;

    protected override void Create()
    {
        MPLOT mPlot         = new MPLOT();
        mPlot.streamSubset = 2; 
        cFunction(mPlot);

        if (mPlot.streamSubset == 44)
             go();  
    }

}

最佳答案

我可以看到以下内容:

  1. 您几乎肯定需要在DllImport 属性中指定cdecl 调用约定。添加 CallingConvention=CallingConvention.Cdecl
  2. 我相信 UnmanagedType.LPStruct 增加了一个额外的间接级别。但是您传递的是 C# class,它是一个引用类型。这意味着您正在将指针传递给指针。这是一个间接级别太多了。首先,完全删除 [In, MarshalAs(UnmanagedType.LPStruct)]。然后你的代码应该工作。如果您为 MPLOT 切换到结构而不是类,那么您需要通过 ref 来获取间接寻址。

我想我会有这样的代码:

[StructLayout(LayoutKind.Sequential)]
public struct MPLOT 
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
    public double []    price;
    public int          streamSubset;
} 

[DllImport("dllname.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void cFunction(
    ref MPLOT mPlot
);

关于c# - 将结构从 c# 传递到 C dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11305557/

相关文章:

c# - 如何在 Entity Framework 5 中使用 SQL Server OFFSET 和 FETCH FIRST?

C# DataGridView 科尔斯潘

c# - PInvoke NetLocalGroupGetMembers 遇到 FatalExecutionEngineError

c# - 从 C# 调用非托管代码 - 返回带有数组的结构

c# - 通过 C# 调用 Win32 api 失败!

c# - 如何使用 Linq (C#) 解析 SVG 样式属性

c# - ASP.NET Core 集成测试在本地工作,但在生产环境中运行时抛出空引用异常

c - TCP 连接断开检测(如果中间链路断开)?

c - 有没有办法读取文件流,直到找到句点 (.)。然后重复?

javascript - 为什么 i^=j^=i^=j 不等于 *i^=*j^=*i^=*j