Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将一个结构与另一个结构的数组从C#传递到C(P/Invoke)_C#_C_Struct_Pinvoke - Fatal编程技术网

将一个结构与另一个结构的数组从C#传递到C(P/Invoke)

将一个结构与另一个结构的数组从C#传递到C(P/Invoke),c#,c,struct,pinvoke,C#,C,Struct,Pinvoke,我的结构如下: [StructLayout(LayoutKind.Sequential)] public struct TCurve { public int fNumItems; /* Number of TRatePts in fArray */ public IntPtr fArray; /* Dates & rates */ // pointer to an array of TRatePt[] public lo

我的结构如下:

[StructLayout(LayoutKind.Sequential)]
public struct TCurve
{
    public int fNumItems;             /* Number of TRatePts in fArray */
    public IntPtr fArray;          /* Dates & rates */ // pointer to an array of TRatePt[]
    public long fBaseDate;            /* Discount date */
    public double fBasis;         //ZERO_CURVE_BASIS in capvoll.c which is #defined as ANNUAL_BASIS 1   /* Number compounding periods / year */
    public long fDayCountConv;   //ZERO_CURVE_DAY_COUNT_CONV in capvoll.c which is #defined as GTO_ACT_365F; = 2L /* How the year fraction is computed */
    public IntPtr     fClassHandle;  /* C++ class handle implementation */
};
[StructLayout(LayoutKind.Sequential)]
public struct TRatePt
{
    public long fDate;
    public double fRate;
};
TRatePt的定义如下:

[DllImport("alib.dll", EntryPoint = "GtoCapFloorAvgVol")]
    public static extern int CapFloorAvgVol(
        long capStartDate,                  /* (I)  */
        long capExpiryDate,                 /* (I) */
        double[] strikeRates,                /* (I) */
        int numStrikeRates,                  /* (I) */
        double[] principles,                 /* (I) */
        int numPrinciples,                   /* (I) */
        int moneymarketDen,                  /* (I) # days/year */
        ref TDateInterval resetPeriod,       /* (I) Time Between caplets */
        int optionType,                      /* (I) Cap or Floor */
        char stubPosition,                   /* (I) 2/16/94 GG 'F'ront or 'B'ack */
        [In] IntPtr zeroCurve,                /* (I) For discounting Pointer to TCurve*/
        double price,                        /* (I) Price */
        double avgVolGuess,                  /* (I) Average Volatility guess */
        out double avgVol);                  /* (O) Average Volatility */
C声明是:

GTO_EXPORT(int )  GtoCapFloorAvgVol(
TDate capStartDate,                  /* (I)  */
TDate capExpiryDate,                 /* (I) */
double *strikeRates,                 /* (I) */
int numStrikeRates,                  /* (I) */
double *principles,                  /* (I) */
int numPrinciples,                   /* (I) */
int moneymarketDen,                  /* (I) # days/year */
TDateInterval *resetPeriod,          /* (I) Time Between caplets */
int optionType,                      /* (I) Cap or Floor */
char stubPosition,                   /* (I) 2/16/94 GG 'F'ront or 'B'ack */
TCurve *zeroCurve,                   /* (I) For discounting */
double price,                        /* (I) Price */
double avgVolGuess,                  /* (I) Average Volatility guess */
double *avgVol)                      /* (O) Average Volatility */
提前谢谢

好的,下面是C结构:

typedef struct _TCurve{
int       fNumItems;     /* Number of TRatePts in fArray */
TRatePt  *fArray;        /* Dates & rates */
TDate     fBaseDate;     /* Discount date */ 
double    fBasis;        /* Number compounding periods / year */
long      fDayCountConv; /* How the year fraction is computed */
void     *fClassHandle;  /* C++ class handle implementation */ } TCurve;
以及:

顺便说一句,如果你知道如何处理这个空白*欢迎帮助

注:TDate只是一个
typedef long int TDate

下面是我如何使用它:

TCurve _zeroCurve = new TCurve()
                        {
                            fBaseDate = _tempValueDate,
                            fNumItems = _ratePoints.Length,
                            fBasis = 2L,
                            fDayCountConv = 1
                        };
        int _sizeOfTCurve = Marshal.SizeOf(typeof(TCurve));
        IntPtr p_zeroCurve = Marshal.AllocHGlobal(_sizeOfTCurve);
        Marshal.StructureToPtr(_zeroCurve, p_zeroCurve, false);

        int _status;
        _zeroCurve.fArray = Marshal.AllocHGlobal(_ratePoints.Length * Marshal.SizeOf(typeof(TRatePt)));
        try
        {
            IntPtr _ratePt = _zeroCurve.fArray;
            for (int _i = 0; _i < _ratePoints.Length; _i++)
            {
                Marshal.StructureToPtr(_ratePoints[_i], _ratePt, false);
                //_ratePt = new IntPtr(_ratePt.ToInt64() + Marshal.SizeOf(typeof(TRatePt)));
                IntPtr _nextRatePt = new IntPtr(_ratePt.ToInt64() + Marshal.SizeOf(typeof(TRatePt)));
                _ratePt = _nextRatePt;
                //_ratePt += Marshal.SizeOf(typeof(TRatePt));
            }
            _status = CapFloorAvgVol(_tempStartDate, _temPexpiryDate, strikeRates, strikeRates.Length, principles, principles.Length, moneymarketDen,
                                            ref _resetPeriod, optionType, stubPosition, p_zeroCurve, price, avgVolGuess, out avgVol);
        }
        finally
        {
            Marshal.FreeHGlobal(_zeroCurve.fArray);
        }

        Marshal.FreeHGlobal(p_zeroCurve);
        p_zeroCurve = IntPtr.Zero;
TCurve\u zeroCurve=new TCurve()
{
fBaseDate=_tempValueDate,
fNumItems=_ratePoints.Length,
fBasis=2L,
fDayCountConv=1
};
int_sizeOfTCurve=Marshal.SizeOf(typeof(TCurve));
IntPtr p_zeroCurve=Marshal.AllocHGlobal(_sizeOfTCurve);
Marshal.StructureToPtr(_zeroCurve,p_zeroCurve,false);
国际地位;
_zeroccurve.fArray=Marshal.AllocHGlobal(_ratePoints.Length*Marshal.SizeOf(typeof(TRatePt));
尝试
{
IntPtr _ratePt=_zeroccurve.fArray;
对于(int_i=0;_i<_ratePoints.Length;_i++)
{
Marshal.StructureToPtr(_ratePoints[_i],_ratePt,false);
//_ratePt=newintptr(_ratePt.ToInt64()+Marshal.SizeOf(typeof(TRatePt));
IntPtr _nextRatePt=新的IntPtr(_ratePt.ToInt64()+Marshal.SizeOf(typeof(TRatePt));
_ratePt=_nextRatePt;
//_ratePt+=Marshal.SizeOf(typeof(TRatePt));
}
_状态=CapFloorAvgVol(_tempStartDate,_temPexpiryDate,删除,删除。长度,原则,原则。长度,moneymarketDen,
参考重置周期、选项类型、存根位置、p_零曲线、价格、avgVolGuess、out avgVol);
}
最后
{
Marshal.FreeHGlobal(_zeroCurve.fArray);
}
自由球元帅(p_零曲线);
p_zeroCurve=IntPtr.Zero;

好的,下面是我认为你的意思,很抱歉我花了这么长时间才弄明白。您需要对指向
TCurve
的指针使用手动编组

为了方便,我简化了你的结构

[StructLayout(LayoutKind.Sequential)]
public struct TCurve
{
    public int fNumItems;            
    public IntPtr fArray;//you need to marshal this manually
};
...
[DllImport("alib.dll", EntryPoint = "GtoCapFloorAvgVol")]
public static extern int CapFloorAvgVol(
    ...
    TCurve ref zeroCurve,
    ...
);
...
TCurve curve = new TCurve();
TRatePt[] items = new TRatePt[2];
//for example, but you'd have the items coming in as a parameter I guess

curve.fNumItems = items.Length;
curve.fArray = Marshal.AllocHGlobal(items.Length * Marshal.SizeOf(typeof(TRatePt)));
try
{
    IntPtr item = curve.fArray;
    for (int i = 0; i < items.Length; i++)
    {
        Marshal.StructureToPtr(items[i], item, false);
        item = new IntPtr(item.ToInt64() + Marshal.SizeOf(typeof(TRatePt))); 
    }
    //now call the function passing the curve struct
}
finally
{
    Marshal.FreeHGlobal(curve.fArray);
}
[StructLayout(LayoutKind.Sequential)]
公共结构曲线
{
公共国际项目;
public IntPtr fArray;//您需要手动封送
};
...
[DllImport(“alib.dll”,EntryPoint=“gtocapflooravvol”)]
公共静态外部设备(
...
t曲线参考零点曲线,
...
);
...
t曲线=新的t曲线();
TRatePt[]项=新TRatePt[2];
//例如,但我想您会将项目作为参数输入
curve.fNumItems=项目长度;
curve.fArray=Marshal.AllocHGlobal(items.Length*Marshal.SizeOf(typeof(TRatePt));
尝试
{
IntPtr项目=curve.fArray;
对于(int i=0;i
我怀疑
Pack=1
是否正确。在C中打包结构是非常罕见的

另一个问题是,<代码>长< /C> > C中的64位,但 long int , INT/COD>都是Windows上的32位C++。
最后,
void*
参数是一个不透明的指针,您应该在C#struct中将其声明为
IntPtr

它不是在处理不安全的结构吗

[StructLayout(LayoutKind.Sequential)]
public unsafe struct TCurve
{
    public TRatePt* fArray;          /* Dates & rates */ // pointer to an array of TRatePt[]
};
[StructLayout(LayoutKind.Sequential)]
public unsafe struct TRatePt
{
    public long fDate;
    public double fRate;
};
然后,在代码中:

unsafe
{
     TCurve _zeroCurve = new TCurve();
     var arr = new TRatePt[]{new TRatePt(), new TRatePt()};
     fixed (TRatePt* pt = arr)
     {
          _zeroCurve.fArray = pt;
          // do sthing while your array is fixed
     }
 }

你能给我们结构的C声明吗?另外,C中的a
long
实际上意味着C中的
int
——C中的a
long
是C中的a
long
。你需要手动封送数组。它往哪个方向走?输入还是输出?谢谢,我是否也需要这样做才能将TCurve传递给函数?当然可以!您的TCurve也包含所有其他字段。我刚刚删除了它们,并将重点放在了您被卡住的位上。很抱歉,我的意思是,我是否也需要将其作为IntPtr传递,或者ref TCurve是否正常?我收到了这些错误:错误37运算符“+=”无法应用于“System.IntPtr”类型的操作数,而“int”错误38无法将类型“int”隐式转换为“System.IntPtr”。存在显式转换(是否缺少演员阵容?)我在.NET4上。您必须使用早期版本。阅读本文以了解如何应对缺失的功能:我没有尝试,但我认为我更喜欢不使用不安全代码。无论如何,多亏了@JonathanDisckon,我解决了这个问题
unsafe
{
     TCurve _zeroCurve = new TCurve();
     var arr = new TRatePt[]{new TRatePt(), new TRatePt()};
     fixed (TRatePt* pt = arr)
     {
          _zeroCurve.fArray = pt;
          // do sthing while your array is fixed
     }
 }