2014-11-14 4 views
5

में फ़ंक्शन को कॉल करने के लिए कॉल करता है, मैं MATLAB में एक डीएलएल लोड करने की कोशिश कर रहा हूं जो किसी अन्य डीएलएल में परिभाषित कार्यों को कॉल करता है। मैं इन सबके लिए नया हूं, और अभी तक यह पता लगाने में सक्षम नहीं हूं कि मैं ऐसा करने के बारे में कैसे जाऊंगा, और न ही मैंने कोई प्रासंगिक संसाधन ढूंढने में कामयाब रहा है।एक सी ++ डीएलएल को मैटलैब में लोड करें जो किसी अन्य डीएलएल

//example_dll.h 
#ifndef EXAMPLE_DLL_H 
#define EXAMPLE_DLL_H 

#ifdef __cplusplus 
extern "C" { 
#endif 

#ifdef BUILDING_EXAMPLE_DLL 
#define EXAMPLE_DLL __declspec(dllexport) 
#else 
#define EXAMPLE_DLL __declspec(dllimport) 
#endif 

int EXAMPLE_DLL Double(int x); 

#ifdef __cplusplus 
} 
#endif 

#endif // EXAMPLE_DLL_H 

और स्रोत फ़ाइल:

मैं सी ++ में एक छोटा सा DLL जो कुछ इस तरह चला जाता है लिखा

//example_dll.cpp 
#include <stdio.h> 
#include "example_dll.h" 

int Double(int x) 
{ 
     return 2 * x; 
} 

यह मैं MinGW W64 का उपयोग कर बनाया गया है और किसी भी बिना loadlibrary('example_dll') का उपयोग कर matlab में लोड समस्या का।

मैं अब एक और DLL में समारोह

int Double(int x) 
{ 
     return 2 * x; 
} 

परिभाषित करने के लिए, और मेरे example_dll से कि समारोह कॉल करने के लिए (यह DLL2 कॉल) चाहते हैं। इसे करने का सबसे आसान तरीका क्या होगा?

मैं एक संक्षिप्त उदाहरण कोड (अधिमानतः रन-टाइम गतिशील लिंकिंग के लिए, और मॉड्यूल परिभाषा (.def) फ़ाइलों के उपयोग के बिना) या इंटरवब्स पर प्रासंगिक संसाधन के लिंक के लिए सराहना करता हूं। धन्यवाद!

सरल उदाहरण का हल:

मुझे लगता है मैं समाधान मिल गया लगता है। ऐसा लगता है कि वैसे भी काम कर रहा है।

मुझे DLL interface_DLL जो मैं MATLAB में लोड नामित और जिसमें से मैं example_dll

यहाँ मेरी समारोह बुलाया बनाया है:

//interface_dll.h 
#ifndef INTERFACE_DLL_H 
#define INTERFACE_DLL_H 

#ifdef __cplusplus 
extern "C" { 
#endif 

#ifdef BUILDING_INTERFACE_DLL 
#define INTERFACE_DLL __declspec(dllexport) 
#else 
#define INTERFACE_DLL __declspec(dllimport) 
#endif 


int INTERFACE_DLL Quadruple(int x); 

#ifdef __cplusplus 
} 
#endif 

#endif // INTERFACE_DLL_H 

और स्रोत फ़ाइल:

//interface_dll.cpp 
#include <windows.h> 
#include <stdio.h> 
#include "interface_dll.h" 
#include "example_dll.h" 

int Quadruple(int x) 
{ 
    /* get handle to dll */ 
    HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\Users\\uidr0605\\Documents\\ExampleDLL\\example_dll.dll"); 

    /* get pointer to the function in the dll*/ 
    FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"Double"); 

    /* 
    Define the Function in the DLL for reuse. This is just prototyping the dll's function. 
    A mock of it. Use "stdcall" for maximum compatibility. 
    */ 
    typedef int (__stdcall * pICFUNC)(int); 

    pICFUNC Double; 
    Double = pICFUNC(lpfnGetProcessID); 

    /* The actual call to the function contained in the dll */ 
    int intMyReturnVal = Double(x); 
    intMyReturnVal = Double(intMyReturnVal); 

    /* Release the Dll */ 
    FreeLibrary(hGetProcIDDLL); 

    /* The return val from the dll */ 
    return intMyReturnVal; 
} 

मैं इसे MATLAB से लोड करता हूं:

%loadDLL.m 
path = 'C:\Path\to\DLL\'; 
addpath(path); 
loadlibrary('interface_dll') 
i = 2; 
x = calllib('interface_dll', 'Quadruple', i) 

कारण मैं इस प्रक्रिया के माध्यम से जा रहा हूँ कि the MATLAB shared library interface supports C library routines only and not C++ classes.

एक समाधान का मेरा विचार MATLAB और DLL कक्षाएं मैं का उपयोग करने का इरादा है, जो के बीच एक अंतरफलक के रूप में कार्य करने के लिए एक मध्यवर्ती DLL उपयोग करने के लिए है। क्या ऐसा करने का कोई बेहतर तरीका है?

आगे प्रश्न:

किसी रूप में यहाँ लागू किया लाइन typedef int (__stdcall * pICFUNC)(int); के महत्व के बारे में समझाएं कर सकते हैं? मुझे क्या जोड़ना होगा या मुझे क्या करना होगा यदि मैं example_dll में कक्षा में कोई फ़ंक्शन कॉल करना चाहता हूं?

संपादित करें:

class EXAMPLE_DLL MyClass 
{ 
public: 
     int add2(int); 
}; 


#ifdef __cplusplus 
extern "C" { 
#endif 


MyClass EXAMPLE_DLL *createInstance(){ 
     return new MyClass(); 
} 

void EXAMPLE_DLL destroyInstance(MyClass *ptrMyClass){ 
     delete ptrMyClass; 
} 

#ifdef __cplusplus 
} 
#endif 

उत्तर

2

इसके अलावा प्रश्न 1

निम्नलिखित परिभाषा

typedef int (__stdcall * pICFUNC)(int); 

एक नए प्रकार pICFUNC है जो परिभाषित करता है: मैं example_dll हेडर फाइल करने के लिए निम्न कोड जोड़ा एक फंक्शन के लिए एक सूचक जो एक int लेता है और एक int देता है। साथ ही, फ़ंक्शन को __stdcall कॉलिंग सम्मेलन के अनुसार बुलाया जाना चाहिए, जो निर्दिष्ट करता है कि तर्क कैसे पारित किए जाने चाहिए और वापसी मूल्य को कैसे प्राप्त किया जाए। यह link फ़ंक्शन पॉइंटर्स के साथ टाइपपीफ बताता है। एक नज़र भी निम्न अनुभाग में, है प्रकार के साथ typedef का उपयोग डाले, लाइन

Double = pICFUNC(lpfnGetProcessID); 

पर के बाद से pICFUNC बजाय कास्ट करने के लिए प्रयोग किया जाता है।

इसके अलावा प्रश्न 2

निम्नलिखित एक बहुत ही तुच्छ उदाहरण एक विचार दे रहा है। आप example_dll बुलाया MyClass जो एक विधि

int add(int num); 

आप निम्नलिखित कार्यों को लागू कर सकता है में एक वर्ग है, तो:

MyClass *createInstance(){ 
    return new MyClass(); 
} 

void destroyInstance(MyClass *ptrMyClass){ 
    delete ptrMyClass; 
} 

ये समारोह होने के लिए extern "सी" और जरूरत आप उन्हें GetProcAddress के साथ आयात कर सकते हैं। फिर, यह एक उदाहरण बनाने का मामला होगा, पॉइंटर के माध्यम से अपनी विधियों को बुलाएगा और अंततः इसे नष्ट कर देगा।

संपादित करें: कार्यान्वयन

आयात उदाहरण

FARPROC lpfnCreateInstance = GetProcAddress(HMODULE (hGetProcIDDLL), "createInstance"); 

समारोह के लिए एक उचित सूचक प्रकार (रिटर्न एक MyClass *, कोई तर्क)

घोषित बनाने के लिए समारोह के लिए कुछ संकेत
typedef MyClass* (__stdcall * pCREATINST)(); 

कास्ट lpfnCreateInstance

pCREATINST createInstance; 

createInstance = pCREATINST(lpfnCreateInstance) 

अपना उदाहरण

MyClass *myInstance = creatInstance(); 

तो फिर तुम ऐड के लिए एक आवरण की जरूरत नहीं है, तो आप सिर्फ अपने सूचक से यह कह सकते हैं।

int res = myInstance->add(123); 

आप प्रकार के साथ सावधान कृपया ध्यान दें कि मैं इस कोड का परीक्षण नहीं कर सकते हैं किया जा रहा है, destroyInstance के लिए भी ऐसा ही करना चाहिए, लेकिन यह सही दृष्टिकोण होना चाहिए।

+0

उत्तर के लिए धन्यवाद। # 1 अब स्पष्ट है। # 2 के लिए मैंने example_dll शीर्षलेख फ़ाइल में अपनी फ़ंक्शन परिभाषाओं को जोड़ा (मेरी मूल पोस्ट में संपादित करें देखें)। मुझे यकीन नहीं है कि अब इंटरफ़ेस_डीएल में इंस्टेंस कैसे बनाएं। अगर आप यह कर सकते हैं कि यह कैसे किया जा सकता है यह दिखाने के लिए आप मेरी इंटरफ़ेस_ डीएल स्रोत फ़ाइल संपादित कर सकते हैं तो मैं इसकी सराहना करता हूं। –

+0

अतिरिक्त जानकारी: प्रोजेक्ट के लिए मैं अंततः इसे लागू करने की योजना बना रहा हूं, मेरे पास केवल हेडर और .lib फ़ाइल उपलब्ध है, और इस प्रकार स्रोत कोड में कोई भी परिवर्तन नहीं कर सकता है। मैं अपने मध्यस्थ डीएलएल से कक्षाओं में निहित कार्यों को कैसे कॉल कर सकता हूं और परिणाम MATLAB पर वापस कर सकता हूं? –

+0

कृपया EDIT पर एक नज़र डालें और इसे उन सुझावों का पालन करने का प्रयास करें। आपके प्रोजेक्ट के लिए, मुझे लगता है कि .lib का मतलब है कि आप DLL के लिए आयात लाइब्रेरी का मतलब है। दुर्भाग्यवश मुझे बाहरी सी रैपर का उपयोग किए बिना सी ++ कोड आयात करने के किसी भी तरीके से अवगत नहीं है। –