我有一个C ++ dll,其中包含不同的三角函数和一些导出的函数,这些函数返回dll信息和结果:
#include "stdafx.h"
#include <cmath>
#include <iostream>
double(*mid)(double);
double csin(double x) {
return std::sin(x);
}
double ccos(double x) {
return std::cos(x);
}
double ctan(double x) {
return std::tan(x);
}
double ccot(double x) {
return 1 / std::tan(x);
}
extern "C" _declspec(dllexport) char* __stdcall get_name() {
char * name = "Trigonometry";
return name;
}
extern "C" _declspec(dllexport) char* __stdcall get_info() {
char * name = "sin|cos|tan|cot";
return name;
}
extern "C" _declspec(dllexport) void __stdcall set_func(char *name) {
if (name == "sin") mid = &csin;
if (name == "cos") mid = &ccos;
if (name == "tan") mid = &ctan;
if (name == "cot") mid = &ccot;
}
extern "C" _declspec(dllexport) double __stdcall calc(double x){
return mid(x);
};
在C#程序中,我尝试调用GetName()
函数以获取我的dll的名称,但是该程序崩溃并显示消息,提示该程序已退出,代码为-1073740940(0xc0000374)。
这是程序崩溃的一部分代码(发生在最后一行执行时):
IntPtr plugin = LoadLibrary(filename);
if (plugin == IntPtr.Zero)
{
Console.WriteLine("Failed to load plugin!");
return;
}
IntPtr func_gn = GetProcAddress(plugin, "_get_name@0");
IntPtr func_gi = GetProcAddress(plugin, "_get_info@0");
IntPtr func_se = GetProcAddress(plugin, "_set_func@4");
IntPtr func_ca = GetProcAddress(plugin, "_calc@8");
if (func_gn == IntPtr.Zero || func_ca == IntPtr.Zero || func_gi == IntPtr.Zero || func_se == IntPtr.Zero)
{
Console.WriteLine("Missing some functions!");
return;
}
Base b = new Base(plugin,
(Base.InfoDelegate)Marshal.GetDelegateForFunctionPointer(func_gn, typeof(Base.InfoDelegate)),
(Base.InfoDelegate)Marshal.GetDelegateForFunctionPointer(func_gi, typeof(Base.InfoDelegate)),
(Base.SetDelegate)Marshal.GetDelegateForFunctionPointer(func_se, typeof(Base.SetDelegate)),
(Base.CalcDelegate)Marshal.GetDelegateForFunctionPointer(func_ca, typeof(Base.CalcDelegate)));
Console.WriteLine("Plugin {0} loaded", b.GetName()); // <- crash here
Base
类:
class Base
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate string InfoDelegate();
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void SetDelegate(string fname);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate double CalcDelegate(double x);
public IntPtr dll;
public InfoDelegate GetName;
public InfoDelegate GetInfo;
public SetDelegate SetFunc;
public CalcDelegate Calc;
public Base(IntPtr dll, InfoDelegate name, InfoDelegate info, SetDelegate set, CalcDelegate calc)
{
this.dll = dll;
this.GetInfo = info;
this.GetName = name;
this.SetFunc = set;
this.Calc = calc;
}
}
执行上述行时,控制台中没有任何内容。它只是关闭而没有任何错误窗口。
什么是错误以及如何解决?
编辑
感谢Hans Passant
的帮助。但事实证明,还有另一个功能不起作用。我尝试通过start
步骤为end
和step
之间的参数打印sin函数的结果。
这是C#代码中发生错误的部分:
plugin.SetFunc("sin");
Console.WriteLine("Result:");
for (double i = start; i <= end; i += step)
{
Console.WriteLine(plugin.Calc(i)); // <- crash here
}
它抛出System.AccessViolationException
。它表示正在尝试访问受保护的内存。我认为这是因为dll代码第5行中的中间指针。有办法解决这个问题吗?