मैं सी ++/सीएलआई प्रतिनिधियों के साथ प्रयोग कर रहा हूं (जैसा कि मैं एक .NET संदर्भ पुस्तकालय बनाने की कोशिश कर रहा हूं), और मुझे निम्न समस्याएं आ रही हैं।सी ++/सीएलआई प्रतिनिधि फंक्शन पॉइंटर (System.AccessViolationException)
मैं सी ++/सीएलआई में एक प्रतिनिधि को परिभाषित करता हूं, और उसके बाद सी # में प्रतिनिधि का एक उदाहरण बना देता हूं, और उसके बाद एक फंक्शन पॉइंटर के माध्यम से अप्रबंधित सी ++ के माध्यम से प्रतिनिधि का उदाहरण कॉल करता हूं। यह सभी उम्मीद के अनुसार काम करता है।
कोड इस (पहले मेरी सी #) को वर्णन करने
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);
}
};
}
और मेरे अप्रबंधित सी ++ फ़ाइल (Unmanaged.cpp)
#include "Unmanaged.hpp"
namespace Unmanaged
{
typedef void (*WriteMessageType)();
WriteMessageType WriteMessageFunc;
void WriteMessage(void* Function)
{
WriteMessageType WriteMessageFunc = (WriteMessageType)(Function);
WriteMessageFunc();
}
}
यह कोड सभी अपेक्षित काम करता है, और आउटपुट "1024" है, क्योंकि विधि() को फ़ंक्शन पॉइंटर द्वारा डेल में बुलाया जाता है egate विधि।
तर्क के साथ एक प्रतिनिधि के साथ एक ही विधि को लागू करने का प्रयास करते समय मेरी समस्या उत्पन्न होती है, जो है: प्रतिनिधि शून्य संदेश डिलीगेट (int संख्या);
मेरे कोड अब इस प्रकार (सी #) है:
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);
}
}
}
मेरे कामयाब सी ++ फ़ाइल:
#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);
}
};
}
और मेरे अप्रबंधित सी ++ फ़ाइल:
#include "Unmanaged.hpp"
namespace Unmanaged
{
typedef void (*WriteMessageType)(int number);
WriteMessageType WriteMessageFunc;
void WriteMessage(void* Function, int number)
{
WriteMessageType WriteMessageFunc = (WriteMessageType)(Function);
WriteMessageFunc(number);
}
}
जब मैं निष्पादित प्रोग्राम मुझे निम्न त्रुटि मिलती है:
अप्रबंधित लाइब्रेरी Test.dll
अतिरिक्त जानकारी: संरक्षित स्मृति को पढ़ने या लिखने का प्रयास किया गया है, के प्रकार का एक अनचाहे अपवाद 'System.AccessViolationException' का एक अनचाहे अपवाद हुआ। यह अक्सर एक संकेत है कि अन्य स्मृति भ्रष्ट है।
संयोग से, कंसोल विंडो 1024 दिखाती है, लेकिन उसके बाद एक यादृच्छिक int (~ 1000000) होती है, और फिर मुझे त्रुटि मिलती है।
मैं इस त्रुटि को प्राप्त करने के कुछ कारणों की कल्पना करना शुरू कर सकता हूं, लेकिन मुझे यकीन नहीं है और मुझे पता लगाने में कठिनाई हो रही है। अगर कोई मुझे बता सकता है कि मुझे यह त्रुटि क्यों मिल रही है, और मैं इसे ठीक करने के लिए क्या कर सकता हूं, तो मैं इसकी सराहना करता हूं।
+1 एक अच्छी तरह से वर्णित प्रश्न –