将固定大小的数组封送为 C# 类的成员不起作用
Marshaling fixed size array as a member of a C# class doesn't work
我在封送类的数组成员时遇到了一个问题。输入类的封送处理很好(我可以在C代码中看到值),但输出类到处都是0。我的C头文件如下:
#pragma pack(push)
#pragma pack(4)
#define MAX_PERIODS 241
#define MAX_REGIONS 60
typedef enum { FNMA, FHLMC }agency_model_type;
typedef struct {
int periods_count;
double test;
double timeline[MAX_REGIONS];
} agency_model_input;
typedef struct {
double wal_years;
double dd_90_rate[MAX_PERIODS];
int test;
} agency_model_output;
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
LIB_API void __stdcall run_agency_model(agency_model_input *model_input, agency_model_output *model_output);
#ifdef __cplusplus
}
#endif
c#部分如下:
public class Model
{
public const int MAX_PERIODS = 241;
public const int MAX_REGIONS = 60;
public enum AgencyModelType { FNMA, FHLMC };
[StructLayout(LayoutKind.Sequential, Pack=4)]
public class AgencyModelInput
{
public int PeriodsCount;
public double test;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_REGIONS)]
public double[] Timeline = new double[MAX_REGIONS];
}
[StructLayout(LayoutKind.Sequential, Pack=4)]
public class AgencyModelOutput
{
public double WAL;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PERIODS)]
public double[] DD90Rate = new double[MAX_PERIODS];
public int test;
}
[DllImport("my-lib.dll", EntryPoint="run_agency_model")]
public static extern void RunAgencyModel(AgencyModelInput input, AgencyModelOutput output);
}
我写了一个单元测试来检查它是否有效。C函数只是将输入增加1,并将它们存储在输出中。下面是测试:
Model.AgencyModelInput input = new Model.AgencyModelInput();
input.PeriodsCount = 10;
input.test = 99;
input.Timeline[0] = 100;
input.Timeline[1] = 200;
Model.AgencyModelOutput output = new Model.AgencyModelOutput();
Model.RunAgencyModel(input, output);
Assert.AreEqual(11, output.WAL);
Assert.AreEqual(100, output.test);
Assert.AreEqual(101, output.DD90Rate[0]);
Assert.AreEqual(201, output.DD90Rate[1]);
测试在第一个断言(输出)上失败。WAL是0。其他的元素也是0。我验证了,输入值被很好地封送,并且在c中可见。
我试图删除包指令,但结果是一样的。
有趣的是,如果我从输出类和C结构体中删除DD90Rate数组,输出。WAL和其他原语字段被正确设置,并且在删除数组上的断言后测试通过。
如果可能的话,我想在c#中继续使用类而不是结构体,因为它们更灵活。我假设类和结构体的内存布局是相同的,这应该不会引起任何问题。
最诚挚的问候,米甲
解决方案是将[Out]属性添加到extern方法中:
[DllImport("my-lib.dll", EntryPoint="run_agency_model")]
public static extern void RunAgencyModel(AgencyModelInput input, [Out] AgencyModelOutput output);
相关文章:
- 为什么 operator() 处的指针成员不起作用?
- 在 C++ 中通过引用传递类成员时,Const 不起作用
- 为什么以下成员初始值设定项在c++中不起作用
- 为什么视频捕获在成员函数中不起作用?
- 为什么static_assert在带有 const 参数的成员函数中不起作用?
- 为什么 SFINAE 在这个简单的成员函数重载中不起作用
- 尝试调用成员函数指针不起作用
- SFINAE:检测成员变量的存在在 g++ 上不起作用
- 在文档中引用使用doxygen的结构成员不起作用;结构成员未出现在文档中
- 模板化类的成员函数的规范化不起作用
- C++中的友元成员函数 - 转发声明不起作用
- 绑定数据成员在VS2012中不起作用
- 优先级队列成员函数不起作用
- C++迭代时删除列表成员:标准解决方案不起作用
- 如果我在静态成员中使用,Qt tr() 不起作用
- 不同类的成员列表实现不起作用
- 在模板类中声明模板成员变量在 Xcode 中不起作用
- 成员函数erase()在循环中不起作用
- sf::Text 成员函数 getFont() 不起作用?
- "类形状"没有名为"info"的成员,但添加一个也不起作用