For learning purposes, I'm trying to load a DLL into MATLAB which calls functions defined in another DLL. I'm new to all of this, and haven't yet been able to figure out how I would go about doing this, and nor have I managed to find any relevant resources.
I wrote a small DLL in C++ which goes something like this:
//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
and the source file:
//example_dll.cpp
#include <stdio.h>
#include "example_dll.h"
int Double(int x)
{
return 2 * x;
}
This I built using MinGW w64 and loaded into matlab using loadlibrary('example_dll')
without any problems.
I now want to define the function
int Double(int x)
{
return 2 * x;
}
In another DLL, (let's call it DLL2) and to call that function from my example_dll. What would be the easiest way to do it?
I would appreciate a short example code (preferably for run-time dynamic linking, and without the use of module definition (.def) files) or a link to a relevant resource on the interwebs. Thanks!
SOLUTION TO SIMPLE EXAMPLE:
I think I got the solution. It seems to be working anyway.
I created a DLL named interface_DLL
which I loaded into MATLAB and from which I called my function in example_dll
here it is:
//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
and the source file:
//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;
}
I load it from MATLAB as follows:
%loadDLL.m
path = 'C:\Path\to\DLL\';
addpath(path);
loadlibrary('interface_dll')
i = 2;
x = calllib('interface_dll', 'Quadruple', i)
The reason I'm going through this process is that the MATLAB shared library interface supports C library routines only and not C++ classes.
My idea of a workaround is to use an intermediate DLL to act as an interface between MATLAB and the DLL who's classes I intend to access. Is there a better way of doing this?
FURTHER QUESTIONS:
Can anyone please explain the significance of the line typedef int (__stdcall * pICFUNC)(int);
as applied here?
What would I have to add or what changes would I have to make if I wanted to call a function in a class in example_dll
?
EDIT: I added the following code to the example_dll header file:
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
Further question 1
The following definition
typedef int (__stdcall * pICFUNC)(int);
defines a new type pICFUNC which is a pointer to a function which takes an int and returns an int. Also, the function must be called according to the __stdcall calling convention, which specifies how arguments must be passed and how to retrieve the return value. This link explains typedef with function pointers. Have a look also at the following section, Using typedef with type casts, since on line
Double = pICFUNC(lpfnGetProcessID);
pICFUNC is used to cast instead.
Further question 2
The following is a very trivial example to give an idea. If you have a class in example_dll called MyClass which has a method
int add(int num);
you could implement the following functions:
MyClass *createInstance(){
return new MyClass();
}
void destroyInstance(MyClass *ptrMyClass){
delete ptrMyClass;
}
These function need to be extern "C" and you could import them with GetProcAddress. Then, it would be just a matter of creating an instance, calling its methods through the pointer and eventually destroying it.
EDIT: Some hints for the implementation
Import the function to create the instance
FARPROC lpfnCreateInstance = GetProcAddress(HMODULE (hGetProcIDDLL), "createInstance");
Declare a proper pointer type for the function (returns a MyClass*, no arguments)
typedef MyClass* (__stdcall * pCREATINST)();
Cast lpfnCreateInstance
pCREATINST createInstance;
createInstance = pCREATINST(lpfnCreateInstance)
Create your instance
MyClass *myInstance = creatInstance();
Then you don't need a wrapper for add, you can just call it from your pointer.
int res = myInstance->add(123);
You should do the same for destroyInstance, being careful with the types Please note that I can't test this code, but it should be the right approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With