2009-02-21 14 views
7

से कार्यों का निर्यात करना मैंने सी ++ डीएल बनाया है जिसे मैं सी # कोड से कॉल करना चाहता हूं। मैं एक समारोह को कॉल करने में सक्षम हूं, लेकिन दूसरा एक अपवाद फेंकता है जब सी # कोड डीएल लोड करने का प्रयास करता है।सी ++ डीएल से सी # पी/

हेडर कुछ इस तरह दिखता है: (? क्या foo = foo नाम क्षेत्र में क्या मतलब है)

extern "C" __declspec(dllexport) BOOL Install(); 
extern "C" __declspec(dllexport) BOOL PPPConnect(); 

यह थोड़ा भ्रमित निर्यात मेज के साथ एक dll का उत्पादन:

File Type: DLL 

Section contains the following exports for PPPManager.dll 

00000000 characteristics 
499F44F0 time date stamp Fri Feb 20 16:04:00 2009 
    0.00 version 
     1 ordinal base 
     2 number of functions 
     2 number of names 

ordinal hint RVA  name 

     1 0 000078E4 Install = Install 
     2 1 000079DC PPPConnect = PPPConnect 

मेरे पी/घोषणाओं को शामिल करें इस तरह दिखते हैं:

[DllImport("PPPManager.dll")] 
private static extern bool Install(); 

[DllImport("PPPManager.dll")] 
private static extern bool PPPConnect(); 

कोई अपवाद के साथ रिटर्न इंस्टॉल करने के लिए कॉल, लेकिन जब मैं PPPConnec को कॉल करता हूं टी, मुझे एक MissingMethodException मिलता है - "PInvoke DLL 'PPPManager.dll' में" एंट्री पॉइंट 'PPPConnect' नहीं मिल रहा है। "

मैंने इंस्टॉलेशन फ़ंक्शन घोषणा से बाहरी और declspec निर्देशों को हटाने का प्रयास किया है, ताकि पीपीपीकनेक्ट एकमात्र फ़ंक्शन निर्यात किया जा सके, और यह अभी भी मुझे PPPConnect को कॉल करने नहीं देता है।

मैंने ऑर्डिनल द्वारा DllImport करने का भी प्रयास किया है; यह नाम के आधार पर कॉल करने के समान परिणाम देता है - रिटर्न इंस्टॉल करें, लेकिन पीपीपीकनेक्ट अपवाद फेंकता है "एंट्री पॉइंट नहीं मिला" # 2 '... "।

इंटरॉप लॉग देता है:

[pinvokeimpl][preservesig] 
bool invivodata.Common.System.IPAQUtils::Install(); 
BOOLEAN (I1_WINBOOL_VAL) Install(); 

JIT ERROR FOR PINVOKE METHOD (Managed -> Native): 
[pinvokeimpl][preservesig] 
bool invivodata.Common.System.IPAQUtils::PPPConnect(); 
BOOLEAN (I1_WINBOOL_VAL) PPPConnect(); 

इस विशेषज्ञता के अपने क्षेत्र के बाहर अच्छी तरह से है, इसलिए किसी भी सुझाव या विचार स्वागत किया जाएगा।

धन्यवाद, पॉल

संपादित करें: ऐसा नहीं है कि इस कोड काम करता है पता चला है; समस्या नवीनतम डीएल के साथ डिवाइस पर प्रचारित नहीं किया जा रहा था। डी 'ओह!

+0

मैं इस इंटरॉप लॉग कभी नहीं सुना गया है - कैसे एक/कि देखने सक्षम है? – Charlie

+0

http://blogs.msdn.com/netcfteam/archive/2005/07/24/442609.aspx मैंने अभी इस समस्या को आजमाने और डीबग करने के लिए इसका उपयोग करना शुरू किया, लेकिन ऐसा लगता है जैसे यह मुझे बहुत बचा सकता MissingMethodExceptions को डिबग करने का समय। – Symmetric

उत्तर

8

क्या आप उन कार्यों को निर्यात करने के लिए अपने डीएलएल प्रोजेक्ट में .def फ़ाइल का उपयोग कर रहे हैं? यदि ऐसा है, तो इसे हटा दें और पुनः प्रयास करें। यह सिर्फ एक अनुमान है क्योंकि ऐसा लगता है कि आपके निर्यात तब नहीं होते जब वे बाहरी "सी" declspec (dllexports) करते हैं।

मैं एक साधारण सी ++ dll

extern "C" __declspec(dllexport) BOOL Install(); 
extern "C" __declspec(dllexport) BOOL PPPConnect(); 

का उपयोग कर और एक साधारण सी # अपने PInvoke घोषणाओं का उपयोग कर अनुप्रयोग के साथ बाहर इस कोशिश की और यह ठीक काम किया।

जब मैं एक DUMPBIN किया/dll मैंने देखा पर निर्यात:

फ़ाइल का डंप PPPManager.dll

फ़ाइल प्रकार: DLL

धारा PPPManager.dll

निम्नलिखित निर्यात होता है
00000000 characteristics 
499F6C2D time date stamp Fri Feb 20 20:51:25 2009 
    0.00 version 
     1 ordinal base 
     2 number of functions 
     2 number of names 

ordinal hint RVA  name 

     1 0 000110CD Install = @ILT+200(_Install) 
     2 1 00011069 PPPConnect = @ILT+100(_PPPConnect) 

ध्यान दें कि निर्यात किए गए नाम मेरे मामले में अलग हैं।

+0

अंत में यह पता चला है कि मैं वीएस में 'प्रोजेक्ट में फ़ाइल जोड़ें' कमांड के बारे में अपनी गलतफहमी के कारण नवीनतम डीएलएल की प्रतिलिपि नहीं बना रहा था। एक स्ट्रिप डाउन डीएलएल का प्रयास करने का आपका विचार वह बीज था जिसे मुझे जाने और उसे समझने की आवश्यकता थी। धन्यवाद! – Symmetric

+0

बढ़िया! मैं खुशी से मदद कर सकता है। –

0

बड़ी जानकारी, लेकिन जैसा कि आप उल्लेख करते हैं, सबकुछ यहां क्रम में है। और Windows के लिए डीबगिंग उपकरण स्थापित करने चलाने की कोशिश करें:

kd -z \path\to\PPPManager.dll -y \path\to\PPPManager.pdb -c "x pppmodule!*" 

प्रतीकों तालिका को बेहतर ढंग से डंप पाने के लिए; यह एक अंधे शॉट के रूप में अच्छी तरह से है, लेकिन आप भी आजमा सकते हैं:

extern "C" 
{ 
    __declspec(dllexport) BOOL Install(); 
    __declspec(dllexport) BOOL PPPConnect(); 
}; 

मामले में __declspec कुछ अजीब कर रही है।

1

यह PPPConnect जितना सरल हो सकता है, जिस तरह से ओएस द्वारा गलत व्याख्या की जाती है। नो-ऑप्स के रूप में Install और PPPConnect दोनों को कार्यान्वित करने का प्रयास करें (बस उन्हें कुछ भी किए बिना TRUE वापस करें) और देखें कि त्रुटि बनी रहती है या नहीं। यदि ऐसा है, तो ऑर्डर को स्वैप करने का प्रयास करें जिसमें वे निर्यात किए जाते हैं (अभी भी नो-ऑप्स के रूप में) और देखें कि क्या समस्या ऑर्डर करने की संभावना है (संभावना नहीं है) या कुछ और।

डीएलएल की निर्यात तालिका की तरह दिखने के लिए आप ग्राफिकल टूल depends का भी उपयोग कर सकते हैं, लेकिन मुझे संदेह है कि समस्या उन तिमाहियों से आ रही है।

+0

असली समस्या को अलग करने के लिए ये अच्छे विचार हैं। आप तीसरे फ़ंक्शन को जोड़ने का प्रयास कर सकते हैं और देख सकते हैं कि उसके साथ क्या होता है। – Charlie

1

आपके विवरण के अनुसार इंस्टॉल करें और पीपीपीकनेक्ट केवल नामों में भिन्न है। मुझे लगता है कि आप अपने सी # एप्लिकेशन के साथ बस पुराने। डीएल संस्करण का उपयोग करें। पीपीपीकनेक्ट के बिना एक परिभाषित किया गया।

घोषणाएं सही दिखती हैं (जहां तक ​​मैं स्रोतों के बिना न्याय कर सकता हूं)।

0

उपयोग निर्भरता वॉकर और सत्यापित करने के लिए क्या तरीके उपलब्ध हैं अपने DLL खोलने

संबंधित मुद्दे