I have a C++ dll that contains different trigonometry functions and some exported functions returning dll information and result:
#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);
};
In C# program I try to call GetName()
function to get the name of my dll but the program crashes with the message that the program exited with the code -1073740940 (0xc0000374).
Here is a part of code where program crashes (it happens when the last line is executed):
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:
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;
}
}
There is nothing in the console when the mentioned line is executed. It just closes without any error windows.
What is the error and how to fix it?
EDIT
Thanks to Hans Passant
for his helpful answer. But there is another function that, as it turned out, does not work. I try to print the results of sin function for arguments in range between start
and end
with the step
step.
Here is the part of C# code where error happens:
plugin.SetFunc("sin");
Console.WriteLine("Result:");
for (double i = start; i <= end; i += step)
{
Console.WriteLine(plugin.Calc(i)); // <- crash here
}
It throws System.AccessViolationException
. It says that there is attempt to access protected memory. I think it is because of that mid pointer in the 5th line of dll code. Is there a way to get over the problem?
User contributions licensed under CC BY-SA 3.0