1

我正在尝试学习足够的 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();  
    }

}

}

4

3 回答 3

1

我可以看到以下内容:

  1. 您几乎肯定需要在属性中指定cdecl调用约定。DllImport添加CallingConvention=CallingConvention.Cdecl.
  2. 我相信这UnmanagedType.LPStruct增加了一层额外的间接性。但是您传递的class是一个引用类型的 C#。这意味着您将指针传递给指针。那是太多的间接级别。首先完全删除[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
);
于 2012-07-03T12:14:32.717 回答
0

尝试明确指定调用约定:

 [DllImport("C:\\Users\\joe\\mcDll.dll", CallingConvention=CallingConvention.Cdecl CharSet = CharSet.Auto)]

VC 默认使用调用约定导出cdecl,但默认DllImport使用stdcall。因此,您必须至少明确指定其中之一,或者更好地同时指定两者。

于 2012-07-03T06:34:46.980 回答
0

替换[In, MarshalAs(UnmanagedType.LPStruct)]ref

于 2012-07-03T06:44:19.297 回答