Я использую Visual Studio 2010 и импортирую собственную C ++ DLL в C #.Когда я просто вызываю функции из DLL и ничего не делаю в своем коде на C #, все работает как надо, но когда я начинаю делать другие вещи в интерфейсе, я получаю ошибку:
Управляемая отладкаПомощник 'FatalExecutionEngineError' обнаружил проблему в 'D: \ Jeff \ 4YP \ ImageViewerApp \ ImageViewerApp \ bin \ Debug \ ImageViewerApp.vshost.exe'.Дополнительная информация: во время выполнения произошла фатальная ошибка.Адрес ошибки был 0x6b4f8127 в потоке 0x1460.Код ошибки 0xc0000005.Эта ошибка может быть ошибкой в CLR или в небезопасных или не поддающихся проверке частях пользовательского кода.Распространенными источниками этой ошибки являются ошибки пользовательского маршалинга для COM-взаимодействия или PInvoke, которые могут повредить стек.
Я считаю, что это проблема повреждения кучи.Я попытался поиграться с кодом в DLL (который в основном экспортирует класс), и мне удалось запустить программу, когда я удаляю все строки, которые присваиваются (не указательным) переменным класса.Но указатели и переменные локальных функций, похоже, не приводят к повреждению.И довольно странно, что в конкретных случаях переменных класса типа int, float, double не происходит искажения, но это происходит для моих пользовательских типов и bool (я не пробовал все типы).
Что может вызвать этот довольно запутанный сценарий?
Вот код из моей C ++ DLL:
#pragma once
#include "stdafx.h"
#include "GlobalClassifier.h"
const int frameRate = 33;
const int jointFeaturesCount = 9;
namespace MyKinectDll
{
typedef struct vector
{
public:
float x;
float y;
float z;
} VECTOR;
[event_receiver(native)]
class __declspec(dllexport) MyKinect
{
public:
MyKinect(void)
{
//Fails when these lines are included:
//initialise hand positions
leftHandPos.x = 0;
leftHandPos.y = 0;
leftHandPos.z = 0;
rightHandPos.x = 0;
rightHandPos.y = 0;
rightHandPos.z = 0;
bGotNewGesture = false;
latestGesture = CClassifier::GestureType::Left_Circular;
//It doesn't fail when these lines are included:
//Create sensor
mySensor = new CNuiSensor();
//Create and initialise classifier
myClassifier = new CGlobalClassifier(mySensor, frameRate, jointFeaturesCount);
myClassifier->Initialise("model.dat");
//Initialise sensor
mySensor->Nui_Init();
};
~MyKinect(void)
{
};
private:
CGlobalClassifier *myClassifier;
CNuiSensor *mySensor;
bool bGotNewGesture;
CClassifier::GestureType latestGesture;
VECTOR leftHandPos;
VECTOR rightHandPos;
};
};
А вот оболочка импорта C #:
struct UnmanWrap
{
//Import constructor
[DllImport("MyKinectDll.dll", EntryPoint = "??0MyKinect@MyKinectDll@@QAE@XZ",
CallingConvention = CallingConvention.ThisCall)]
public static extern void Constructor(ref UnmanWrap t);
}
public class MyKinectWrap
{
private UnmanWrap unman;
public MyKinectWrap()
{
//Add a path to location of the DLL file.
Environment.SetEnvironmentVariable("PATH","D:\\Jeff\\4YP\\MyKinectDll2\\Release");
this.unman = new UnmanWrap();
UnmanWrap.Constructor(ref this.unman);
}
}