如何调用 C++来自 c# 的函数
我正在尝试用 C# 调用大学提供的 C++ 函数。他给我提供了一个dll和下面的头文件。
C++ 标头
#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++代码需要改变吗?
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# 中使用它),因此欢迎任何其他提示等。
I am trying to call a C++ function provided from a college in C#. He has provided me with a dll and the following header file.
C++ Header
#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));
I am using the following C# code to call the above c++ function which results in the following error.
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
How do I call this function in C#? Does the C++ code need to change?
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
}
}
}
More background:
My college has develop several financially related calculations and I am hoping with minimal effort we can reuse his entire library in another C# application. Both he an I have very minimal experience in this area (creating exportable C++ code and using it in C#) so any other tips etc will be welcomed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有机会直接从 C# 调用此函数。
vector<>
与 C#int[]
没有关系。最好的选择是将 C# 库包装在托管 C++ 包装器中,以便您可以在传入时进行从 C# 类型到 C++ 类型的转换,并在传出时进行从 C++ 类型到 C# 类型的映射。
You've got no chance of calling this function directly from C#. A
vector<>
has no relation to a C#int[]
.Your best bet would be to wrap the C# library in a manged C++ wrapper so that you can do the translation from the C# types to the C++ types on the way in, and the mapping from the C++ types to the C# types on the way out.
如果您与该库的开发人员合作(相对于仅使用他的库),可能值得看看他提供的 C++CLI 构建,您可以直接使用标准 C# 来使用它。您需要处理 lib 代码中的向量/stl 使用 - 要么用 cli 列表(或其他托管容器)替换它,要么找到包装器解决方案(有各种关于例如 此处和此处)。
我认为这可能是比基于 pinvoke 的原始 C++ 互操作更容易的长期解决方案。
If you working with the developer of the library (as aposed to just using his lib) it might be worth looking at him providing a C++CLI build that you can work with directly with standard C#. You would need to deal with the vector/stl use in lib code - either replace this with cli Lists (or other managed containers) or find a wrapper solution (There are various SO posts about eg here and here).
I think that is likely going to be easier long term solution than pinvoke based interop to raw C++.