我试图调用C#中的大学提供的C ++函数。他为我提供了一个dll和以下头文件。
#include "../libs/tfvo.h"
extern "C" __declspec(dllexport) vector<double> fvm(
vector<double> yearFractions,
vector<double> discountFactors,
vector<double> weightings,
double alpha_meanReversion,
double sigma_meanReversion,
double alpha_shortRate,
double alpha_meanReversion,
double sigma_shortRate,
vector<double> startingValues = vector<double>(3,0.01));
我使用以下C#代码调用上面的c ++函数,导致以下错误。
“尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”
如何在C#中调用此函数? C ++代码是否需要更改?
var result = SimpleDllTest.testWrapper(); // In a console app
class SimpleDllTest
{
[DllImport("fvm.dll")]
public static extern IntPtr fitVasicekModel(
IntPtr yearFractions,
IntPtr weightings,
double alpha_meanReversion,
double sigma_meanReversion,
double alpha_shortRate,
double sigma_shortRate,
IntPtr startingValues
);
public static double [] testWrapper()
{
var t = new double[] { 0.1, 1.2 };
var v = new double[] { 0.1, 1.2 };
int size = Marshal.SizeOf(t[0]) * t.Length;
IntPtr pnt = Marshal.AllocHGlobal(size);
Marshal.Copy(t, 0, pnt, t.Length);
int sizev = Marshal.SizeOf(v[0]) * v.Length;
IntPtr pntv = Marshal.AllocHGlobal(sizev);
Marshal.Copy(v, 0, pntv, v.Length);
IntPtr result = fitVasicekModel(pnt, pnt, 1, 1, 1, 1, pntv);
try
{
return (double[])Marshal.PtrToStructure(result , typeof(double[]));
}
finally
{
// Free the pointer here if it's allocated memory
}
}
}
更多背景: 我的大学已经开发了几个与财务相关的计算,我希望我们可以用最小的努力将他的整个库重用到另一个C#应用程序中。他和我在这方面的经验非常少(创建可导出的C ++代码并在C#中使用它),所以任何其他提示等都会受到欢迎。
答案 0 :(得分:1)
您无法直接从C#调用此函数。 vector<>
与C#int[]
无关。
最好的办法是将C#库包装在一个manged C ++包装器中,这样你就可以在进程中从C#类型转换为C ++类型,并从C ++类型到C#类型的映射出路。
答案 1 :(得分:0)
如果您与库的开发人员合作(仅仅使用他的lib),可能值得看看他提供的C ++ CLI构建,您可以直接使用标准C#。您需要处理lib代码中的vector / stl用法 - 用cli Lists(或其他托管容器)替换它或找到包装器解决方案(有关于例如here和{{3}的各种SO帖子})。
我认为这可能比基于pinvoke的互操作到原始C ++更容易长期解决。