मैं एक सी डीएल में एक रैपर बनाने की कोशिश कर रहा हूं और मैं एक फ़ंक्शन कॉल करने का प्रयास कर रहा हूं जिसमें कॉलबैक फ़ंक्शन है, प्राप्त करता है एक वस्तु जो एक सूचक के रूप में वापस पारित किया जाता है।मैं सी #+ डीएल में सी # + डीएल में एक फ़ंक्शन कैसे कॉल करूं जिसमें शून्य * कॉलबैक और ऑब्जेक्ट पैरामीटर
ज फ़ाइल delares
extern int SetErrorHandler(void (*handler) (int, const char*, void*),
void *data_ptr);
हैंडलर एक कॉलबैक फ़ंक्शन एक त्रुटि होती है और data_ptr के मामले में, किसी भी वस्तु (राज्य) है कि आप करने के लिए वापस पारित हो जाता है तब होता है जब कहा जाता है वह यह है कि मेरी ऐप जो यह होगा (वर्तमान वस्तु)।
मैं एक डीएल में फ़ंक्शंस को कॉल करने में सक्षम हूं जो सरल प्रकार के तारों, इन्स इत्यादि जैसे मार्शल किए गए निरंतर प्रकारों का उपयोग करता है लेकिन मैं यह नहीं समझ सकता कि कैसे एक सी # ऑब्जेक्ट को पॉइंटर को मार्शल करना है।
सी फ़ंक्शन के ऑब्जेक्ट संदर्भ को यहां से खोजकर जो मिला है उससे प्राप्त करने के लिए और अन्यथा ऐसा लगता है कि मुझे फ़ंक्शन में मार्शल करने में सक्षम होने के लिए संरचना प्रकार की आवश्यकता है, इसलिए मैंने अपनी ऑब्जेक्ट को पकड़ने के लिए एक स्ट्रक्चर बनाया :
[StructLayout(LayoutKind.Sequential)]
struct MyObjectState
{
public object state;
}
संपादित करें: मैं एक विशेषता डालने की कोशिश की: public object state
संपत्ति पर [MarshalAs(UnmanagedType.Struct, SizeConst = 4)]
, लेकिन यह एक ही त्रुटि पैदा करता है, तो मैं इसे हटा दिया, यह does not वैसे भी काम करेगा लगता है।
संरचना में कॉलबैक फ़ंक्शन के लिए किसी ऑब्जेक्ट को रखने के लिए एक ऑब्जेक्ट प्रॉपर्टी होती है।
मैं इस प्रकार सी # में प्रतिनिधि की घोषणा की:
delegate void ErrorHandler(int errorCode, IntPtr name, IntPtr data);
तब मैं सी # में आयात समारोह घोषित इस प्रकार है:
[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int SetErrorHandler handler, IntPtr data);
तब मैं अपने सी # कोड में एक कॉलबैक फ़ंक्शन बनाया:
void MyErrorHandler(int errorCode, IntPtr name, IntPtr data)
{
var strName = Marshal.PtrToStringAnsi(name);
var state = new MyObjectState();
Marshal.PtrToStructure(data, state);
Console.WriteLine(strName);
}
मैं लाइब्रेरी फ़ंक्शन को निम्नानुसार कॉल करने में सक्षम हूं:
var state = new MyObjectState()
{
state = this
};
IntPtr pStruct = Marshal.AllocHGlobal(Marshal.SizeOf(state));
Marshal.StructureToPtr(state, pStruct, true);
int ret = SetErrorHandler(MyErrorHandler, pStruct);
कॉल काम करता है और कॉलबैक फ़ंक्शन कहा जाता है, लेकिन मैं कॉलबैक फ़ंक्शन में डेटा का उपयोग करने में असमर्थ हूँ और जब मैं Marshal.PtrToStructure
कोशिश मैं एक त्रुटि मिलती है:
The structure must not be a value class.
मैं खोज की एक बहुत कुछ किया यहां और मार्शल और शून्य * पर विभिन्न चीजें मिलीं लेकिन कुछ भी मुझे काम करने में मदद नहीं मिली है
धन्यवाद।
इस मामले में यह सच है, वास्तव में मुझे इसे डेटा पर पास करने की ज़रूरत नहीं थी क्योंकि यह मेरे ऑब्जेक्ट कॉलबैक में उपलब्ध होगा, लेकिन जब मैं उपयोगकर्ता चाहता हूं तो फ़ंक्शन को सही कॉल प्रदान करना चाहता था एक संदर्भ प्रदान करें। मुझे लगता है कि राज्य के संदर्भ को बनाए रखने के लिए डेटा के प्रबंधन को सी # ऑब्जेक्ट द्वारा नियंत्रित किया जा सकता है। तो मुझे लगता है कि यह मेरी समस्या हल करता है, लेकिन मुझे लगता है कि ऑब्जेक्ट को पास करना संभव है या नहीं, इसका मूल प्रश्न अनुत्तरित – Andre
है, आप वास्तव में मेरे दृश्य में एक C# ऑब्जेक्ट का संदर्भ पास नहीं करना चाहते हैं। याद रखें कि प्रबंधित वस्तुओं को जीसी द्वारा स्थानांतरित किया जा सकता है। क्या आप ऐसी वस्तुओं को पिन करने के लिए मजबूर कर रहे हैं? और देशी कोड ऐसी चीज के साथ क्या कर सकता है? यह पूरी तरह से अपारदर्शी है। आप प्रत्येक ऑब्जेक्ट के लिए एक अद्वितीय आईडी प्राप्त करने के लिए 'ऑब्जेक्टिड जेनरेटर' का उपयोग कर सकते हैं, लेकिन व्यक्तिगत रूप से मुझे लगता है कि आपका प्रश्न सबसे अच्छा तरीके से इसका सामना कर रहा है! –
जो आप कहते हैं वह समझ में आता है, और मुझे लगता है कि उत्तर ऐसा नहीं करता है/इससे बचें, यह असंभव नहीं हो सकता है लेकिन आपको नहीं चाहिए, धन्यवाद – Andre