Я экспериментировал с делегатами C ++ / CLI (так как я пытался создать справочную библиотеку .NET), и у меня возникла следующая проблема .
Я определяю делегат в C ++ / CLI, а затем создаю экземпляр делегата в C #, а затем вызываю экземпляр делегата через неуправляемый C ++ через указатель на функцию. Все работает так, как ожидалось.
Код, иллюстрирующий это (сначала мой C #)
using System;
namespace TestProgram
{
class Program
{
static void Main(string[] args)
{
Library.Test.MessageDelegate messageDelegate = new Library.Test.MessageDelegate(Message);
Library.Test test = new Library.Test(messageDelegate);
test.WriteMessage();
Console.Read();
}
static void Message()
{
Console.WriteLine(1024);
}
}
}
Затем мой управляемый файл C ++ (Managed.cpp)
#include "Unmanaged.hpp"
#include <string>
namespace Library
{
using namespace System;
using namespace System::Runtime::InteropServices;
public ref class Test
{
public:
delegate void MessageDelegate();
internal:
MessageDelegate^ Message;
void* delegatePointer;
public:
Test(MessageDelegate^ messageDelegate)
{
delegatePointer = (void*)Marshal::GetFunctionPointerForDelegate(messageDelegate).ToPointer();
}
void WriteMessage()
{
Unmanaged::WriteMessage(delegatePointer);
}
};
}
И мой неуправляемый файл C ++ (Unmanaged.cpp)
#include "Unmanaged.hpp"
namespace Unmanaged
{
typedef void (*WriteMessageType)();
WriteMessageType WriteMessageFunc;
void WriteMessage(void* Function)
{
WriteMessageType WriteMessageFunc = (WriteMessageType)(Function);
WriteMessageFunc();
}
}
Весь этот код работает, как ожидалось, и на выходе получается «1024», так как Method () вызывается указателем функции на метод делегата.
Моя проблема возникает при попытке применить тот же метод к делегату с аргументами, а именно: delegate void MessageDelegate (int number);
Мой код теперь выглядит следующим образом (C #):
using System;
namespace AddProgram
{
class Program
{
static void Main(string[] args)
{
Library.Test.MessageDelegate messageDelegate = new Library.Test.MessageDelegate(Message);
Library.Test test = new Library.Test(messageDelegate);
test.WriteMessage(1024);
Console.Read();
}
static void Message(int number)
{
Console.WriteLine(number);
}
}
}
Мой управляемый файл C ++ :
#include "Unmanaged.hpp"
#include <string>
namespace Library
{
using namespace System;
using namespace System::Runtime::InteropServices;
public ref class Test
{
public:
delegate void MessageDelegate(int number);
internal:
MessageDelegate^ Message;
void* delegatePointer;
public:
Test(MessageDelegate^ messageDelegate)
{
delegatePointer = (void*)Marshal::GetFunctionPointerForDelegate(messageDelegate).ToPointer();
}
void WriteMessage(int number)
{
Unmanaged::WriteMessage(delegatePointer, number);
}
};
}
И мой неуправляемый файл C ++:
#include "Unmanaged.hpp"
namespace Unmanaged
{
typedef void (*WriteMessageType)(int number);
WriteMessageType WriteMessageFunc;
void WriteMessage(void* Function, int number)
{
WriteMessageType WriteMessageFunc = (WriteMessageType)(Function);
WriteMessageFunc(number);
}
}
Когда я запускаю программу, я получаю следующую ошибку:
Необработанное исключение типа 'System.AccessViolationException' произошло в Unmanaged Library Test.dll
Дополнительная информация: Попытка прочитать или записать в защищенную память. Это часто указывает на то, что другая память повреждена.
Между прочим, в окне консоли действительно отображается 1024, но затем следует случайное целое число (~ 1000000), а затем я получаю сообщение об ошибке.
Я могу представить себе некоторые из причин, по которым я получаю эту ошибку, но я не уверен и затрудняюсь выяснить. Если бы кто-нибудь мог сказать мне, почему я получаю эту ошибку, и что я могу сделать, чтобы ее исправить, я был бы очень признателен.