Load a C++ DLL into matlab which calls functions in another DLL - c++

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.

Related

C++ Export array from DLL to invoke/use in C based program

Hello I am currently trying to export an array from a Dll into a C-based data-analysis program called Uniplot.
I am able to call the DLL and get it running, though I cant access the data provided by the Dll. I am not really well-served on this subject but I am guessing it has something to do with releasing the function to get rid of the pointers, or the data type in general even.
Header.h
// considering export into C application
#ifdef __cplusplus
extern "C"
{
#endif
// prepare functions for later export/import from DLL
#ifdef CALC_EXPORTS
#define CALCDLL_API __declspec(dllexport)
#else
#define CALCDLL_API __declspec(dllimport)
#endif
typedef double t_mda[150];
typedef double t_sda[50];
typedef double t_oda[150];
/*===========================
functions
============================*/
// general function
CALCDLL_API double* CALC (t_mda MDA, t_sda SDA);
....
#ifdef __cplusplus
}
#endif
.cpp
t_oda ODA;
CALCDLL_API double* CALC (t_mda MDA, t_sda SDA) {
...
//data output
return ODA;
}
CALC is generating the data and saving it to the ODA-array which I would like to use in another application. What are the changes I need to make to get that running?

C++: Creating a Callback function of the correct type

I am working on a wrapper to use a hardware component in python using a dll provided by the manufactuer. The DLL comes with header and lib files so it is easy to include the dll.
As far as I understand, the compnent is used by calling the open function giving some initial parameters a callback function and some additional user data to it and then call the start method. In the following the component will deliver data by calling the callback function.
The header of the dll looks something like this:
#ifndef COMPONENT_DLL_INCLUDED
#define COMPONENT_DLL_INCLUDED
#pragma once
#ifndef DYNAMIC_COMPONENT_DLL_LINKAGE
// to allow include in C- and C++-code
#ifndef DLL_DECLSPEC
#ifdef __cplusplus
#define DLL_DECLSPEC extern "C" __declspec(dllimport)
#else
#define DLL_DECLSPEC __declspec(dllimport)
#endif
#endif
typedef struct{
eInformationType type;
eResultType error;
ComponentInfo info;
}AsyncInfo;
typedef struct{
BOOL someParameter;
BOOL someParameter2;
} ParamSet1;
typedef enum eType {
UndefinedType = 0x0,
Type1 = 0x1,
Type2 = 0x2
} Param2;
// exported type SendAsynInformation
typedef void ( CALLBACK *SendAsyncInformation )( const AsyncInfo&, void *userInfo);
// exported functions
DLL_DECLSPEC eResultType COMPONENT_Open( const ParamSet1 Set1, const Param2 P2, SendAsyncInformation SendAsyncInfo, void *userInfo );
DLL_DECLSPEC eResultType COMPONENT_Start( void );
My question is, how must my callback function look like? I tried things like
void myCallback(AsyncInfo *Info, myGlobals *g)
{
...something...
}
and then pass this callback to the open function:
COMPONENT_Open(mySet1, myP2, myCallback, myVoidPtr);
But I always get errors like:
...cannot convert argument 3 from 'void (__cdecl *)(AsyncInfo *,myGlobals *)' to 'SendAsyncInformation'
I am rather new to C++ so most likely this is a trivial question. I tried numerous things, but I don't see how to do it right. So, what is my mistake?
You need to define the myCallback as
void CALLBACK myCallback(const AsyncInfo&, void *userInfo)
{ ... }
and call the COMPONENT_Open as
COMPONENT_Open(mySet1, myP2, (SendAsyncInformation)&myCallback, myVoidPtr);
The CALLBACK keyword (or macro actually) in the function prototypes dictates the compiler what calling convention it's suppose to use, which if doesn't match could give you the exception during the stack frame cleanup time.
Since the COMPONENT_Open function accepts the callback as a type SendAsyncInformation which is a typedef, therefore you need to cast the address of your myCallback to the SendAsyncInformation.

Using a C/C++ DLL with FreePascal

First of all I am using Mingw 4.8 as the compiler of the C++ DLL in Code:blocks 13.12 and Lazarus 1.4.2 for working with the pascal code.(windows 7)
I need to generete a dll in c++ or c that can be called from a pascal program.
The problem is that my knowlegde about pascal is null, It dosn't look really complicate to make a simple program but I can't find good information about how to import and use a C/C++ DLL.
The only thing that moreless worked was this: http://www.drbob42.com/delphi/headconv.htm
My real code:
Pascal:
funtion hello():Integer; external 'function' index 1;
...
Label1.Caption:=IntToStr(hello());
C++ DLL header:
#ifndef function_H
#define function_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL hello( );
#ifdef __cplusplus
}
#endif
#endif
C++ file:
#include <stdio.h>
#include "function.h"
__stdcall int hello( )
{
return 8;
}
But when try to pass any argument or do something complicated with the function,starts to give randoms numbers.
This is the new code:
Pascal:
function function1(t1:Integer):Integer; external 'function' index 1;
...
entero:=8;
Label1.Caption:=IntToStr(function1(entero2));
Also I update the c++ code to this:
C++:
#include <stdio.h>
#include "function.h"
__stdcall int function1(int t1)
{
return t1*2;
}
Header:
#ifndef funtion_H
#define funtion_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL function1(int t1);
#ifdef __cplusplus
}
#endif
#endif
I aslo read this other info:http://www.jrsoftware.org/ishelp/index.php?topic=scriptdll. And tried to implement the dll call like this:
Pascal:
function function1(t1: Integer): Integer; external 'function1#files:function.dll';
But I receive an error saying that:
The procedure entry point function1 could not be located in the
dynamic link library function.dll
I'm looking for an example that works or a online tutorial or something to continue working because I am very stuck with this.
Thank you in advance.
You need to make the calling conventions match. Your C++ code uses __stdcall. The Pascal code does not specify a calling convention and so defaults to register.
Declare the Pascal import like this:
function function1(t1:Integer):Integer; stdcall; external 'function' index 1;
Are you quite sure that you need to use an index when importing? It is much more common to import by name than by ordinal. I'd expect to see the import looking like this:
function function1(t1:Integer):Integer; stdcall; external 'function';
The reason why the function with no parameters succeeds is that for a parameterless function, the differences between calling convention do not matter. Once you start passing an argument, stdcall means that the argument is passed via the stack, and register means it is passed in a register. This mismatch explains the behaviour you observe.

Using a mixed C/C++ header to use C++ object in C

I have been following this guide on how to call a member function of a C++ object from C. As I've understood it, the C code should interpret the class as a struct of the same name, and whenever it wants to call a function through an object of this class it should use an intermediate callback function. The header looks like this:
// CInterface.h
#ifdef __cplusplus
...
class CInterface
{
public:
...
void OnMessage(U8* bytes); // I want to call this function from C.
private:
...
};
#else
typedef
struct CInterface
CInterface;
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__STDC__) || defined(__cplusplus)
//extern void c_function(CInterface*); /* ANSI C prototypes (shouldn't be needed) */
extern CInterface* cpp_callback_function(CInterface* self, unsigned char * bytes);
#else
//extern void c_function(); /* K&R style (shouldn't be needed) */
extern CInterface* cpp_callback_function(unsigned char * bytes);
#endif
#ifdef __cplusplus
}
#endif
The C code that fails right now looks like this:
// main.c
#include "CInterface.h"
int main(int argc, char* argv[])
{
void* ptr;
int *i = ptr; // Code that only compiles with a C compiler
CInterface cinterface; // This should declare a struct
}
The error is: error C2079: 'cinterface' uses undefined struct 'CInterface'.
It sounds like the header is being read as c++ code as the struct is not defined, but main.c is being compiled by C according to Visual Studio (I also double checked this by adding some C-specific code). However, if I add parentheses like this:
CInterface cinterface();
the code compiles which makes no sense to me as it now is an object which shouldn't work in C.
The callback function is implemented in a third file, CInterface.cpp, which acts as the "intermediate".
So the question is how I solve this error message, or if I got the entire approach wrong. It's the first time I mix C/C++ code and I'm relatively new to both languages.
In your example CInterface is only defined for C++. If you take a closer look at the example you linked you'll notice that this is also the case for the Fred class.
From C you can only pass around pointers to CInterface and you have to rely on C++ functions defined with C linkage to actually manipulate CInterface instances.
Otherwise you could define a struct as a means to pass around data between C and C++. Just ensure its definition is declared as extern "C" when used from C++:
#ifdef __cplusplus
extern "C" {
#endif
struct CandCPlusPlus {
// ...
};
#ifdef __cplusplus
}
#endif

How to call a c++ class and its method from a c file

I am trying to access a C++ class and call its method from a .c file.
I google this topic and find this http://developers.sun.com/solaris/articles/mixing.html
It says:
You can write extern "C" functions in C++ that access class M objects and call them from C code.
Here is a C++ function designed to call the member function foo:
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }
My question is where do I put the about line? In my C++ .h file? Or C .h file?
And it goes on and says:
Here is an example of C code that uses class M:
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{
return call_M_foo(p, j);
}
But how/where do I create the class M in my C file?
And where do I put the above code? C .h file? C++ .h file? Or C .c file?
Thank you.
Thank you for GMan's detailed answer.
I did follow your suggestion. But I get compile error in my .c file.
main.c:33:
./some_class.h:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘’ token
./some_class.h:25: error: expected ‘)’ before ‘’ token
./some_class.h:26: error: expected ‘)’ before ‘*’ token
And here are my some_class.h line 24-26:
#ifdef __cplusplus
class M {
public:
M();
virtual ~M();
void method1(char* name, char* msg);
};
extern "C" {
#else
struct M;
#endif
/* access functions line 24-26 are here*/
M* M_new(void);
void M_delete(M*);
void M_method1(M*, char*, char*);
#ifdef __cplusplus
}
#endif
For some reason, my C compiler does not like extern "C" in GMan's original some_test.h. So I have to modify to above. It seems like the C compiler does not like/understand the struct M; line.
Any idea will be much appreciated.
Your header file, which is shared between your C and C++ code:
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
EXPORT_C some_class* some_class_new(void);
EXPORT_C void some_class_delete(some_class*);
EXPORT_C int some_class_some_method(some_class*, float);
Then your source file:
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C some_class* some_class_new(void)
{
return new some_class();
}
EXPORT_C void some_class_delete(some_class* this)
{
delete this;
}
EXPORT_C int some_class_some_method(some_class* this, float f)
{
return this->some_method(f);
}
Now compile that source, and link to it. Your C source would be something like:
#include "some_class.h"
some_class* myInstance = some_class_new();
int i = some_class_some_method(myInstance, 10.0f);
some_class_delete(myInstance);
If you're serious about mixing C and C++, you'll want macro's.
Here are some sample macro's that would make this much easier:
// in something like c_export.h
// extern "C" macro
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
// new
#define EXPORT_C_CLASS_NEW(classname) EXPORT_C \
classname * classname##_new(void)
#define EXPORT_C_CLASS_NEW_DEFINE(classname) \
EXPORT_C_CLASS_NEW(classname) \
{ return new classname (); }
// repeat as much as you want. allows passing parameters to the constructor
#define EXPORT_C_CLASS_NEW_1(classname, param1) EXPORT_C \
classname * classname##_new( param1 p1)
#define EXPORT_C_CLASS_NEW_1_DEFINE(classname, param1) \
EXPORT_C_CLASS_NEW_1(classname, param1) \
{ return new classname (p1); }
// delete
#define EXPORT_C_CLASS_DELETE(classname) EXPORT_C \
void classname##_delete( classname * this)
#define EXPORT_C_CLASS_DELETE_DEFINE(classname) \
EXPORT_C_CLASS_DELETE(classname) \
{ delete this; }
// functions
#define EXPORT_C_CLASS_METHOD(classname, methodname, ret) EXPORT_C \
ret classname##_##methodname##( classname * this)
#define EXPORT_C_CLASS_METHOD_DEFINE(classname, methodname, ret) \
EXPORT_C_CLASS_METHOD(classname, methodname, ret) \
{ return this->##methodname##(); }
// and repeat as necessary.
#define EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) EXPORT_C \
ret classname##_##methodname( classname * this, param1 p1)
#define EXPORT_C_CLASS_METHOD_1_DEFINE(classname, methodname, ret, param1) \
EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) \
{ return this->##methodname##(p1); }
And so on. Our header/source becomes:
// header
#include "c_export.h" // utility macros
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
EXPORT_C_CLASS_NEW(some_class);
EXPORT_C_CLASS_DELETE(some_class);
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float);
// source
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C_CLASS_NEW_DEFINE(some_class);
EXPORT_C_CLASS_DELETE_DEFINE(some_class);
EXPORT_C_CLASS_METHOD_1_DEFINE(some_class, some_method, int, float);
And that's much more concise. It could be made simpler (possibly) with variadic macro's, but that's non-standard and I leave that to you. :] Also, you can make macro's for normal non-member functions.
Note that C does not know what references are. If you want to bind to a reference, your best bet is probably just to write the export definition manually. (But I'll think about it, maybe we can get it automatically).
Imagine our some_class took the float by (non-const)reference (for whatever reason). We'd define the function like so:
// header
// pass by pointer! v
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float*) ;
// source
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float*)
{
// dereference pointer; now can be used as reference
return this->some_method(*p1);
}
And there we go. C would interface with references with pointers instead:
// c source, if some_method took a reference:
float f = 10.0f;
int i = some_class_some_method(myInstance, &f);
And we pass f "by reference".
You need to split it among the C++ header and implementation files.
foo.h:
extern "C" int call_M_foo(M* m, int i);
foo.cc:
extern "C" int call_M_foo(M* m, int i) {
return m->foo(i);
}
To create the object of type M, you would need a similar function:
foo.h:
struct M;
extern "C" M* create_M();
foo.cc:
extern "C" M* create_M() {
return new M;
}
You have several questions combined here so I will answer them individually.
My question is where do I put the about line? In my c++ .h file? or c .h file?
The extern "C" line goes in the C++ file. It essentially tells the compiler to
limit everything whithin the extern "C" block to the C subset of C++, and to
export functions declared in this area accordingly.
But how/where do I create the class M in my c file?
You can't. C does not have the concept of classes, and there's absolutely no
way to instantiate a class directly. You essentially have to export a C function
in your C++ file which creates the class and returns it as a pointer. Then you
can pass that pointer around your C application. You can't actually modify the
class directly in your C application, because C does not support classes, and
your C++ compiler may insert "hidden" variables for bookkeeping inside the
actual declaration of the class.
And where do I put the above code?
The piece of code that uses a structure pointer goes in the C file. You are
forced to use a structure pointer because C does not support classes at all.
You can put function calls using that function anywhere in a C implementation
file, just like normal C function calls.
All the information you need is in the link you provide. You just need to understand that there needs to be a strict separation between C and C++ code.
C++ code can call any C code.
C code usually cannot call any C++ code.
C functions can be implemented by C++ code.
The key part to understand is that the C and C++ compilers mangle function names when making object files in different ways, so they would normally not be able to interoperate (at link time), except that C++ can be prompted to know the difference by using extern "C"
The prototype:
void f(int); might be mangled by a C compiler to: _f, but a C++ compiler might choose a very different name eg f_int, and so the linker would not know they are supposed to be the same.
However:
extern "C" void f(int);
would be mangled by a C++ compiler to _f, but a C compiler would choke on the extern "C". To avoid this you should used something like this:
#ifdef __cplusplus
extern "C" {
#endif
void f(int);
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
Now the whole of the above section can live in a .h file and is, as the sun.com article states, a mixed-language header.
This means that a .c or .cpp file can #include this header and code can call f();
and either a .c or .cpp file can #include this header and implement it:
void f()
{
}
Now the good bit is that a .cpp file can implement this to call any C++ code it likes.
Now to answer your specific questions:
The first code sample can only go in a .cpp file.
The second code sample can only go in a .c file.
Additionally class M must be declared and defined in C++ files only.
The site you have linked to has the answer already:
You can declare function print in a
header file that is shared by C and
C++ code:
#ifdef __cplusplus extern "C"
#endif int print(int i, double d);
You can declare at most one function
of an overloaded set as extern "C"
Here is the example C header for the
wrapper functions:
int g_int(int);
double g_double(double);
Basically, there can be a header shared between the two that declares the function prototype, adding the extern "C" modifier if you are in C++ to ensure the function can be accessed in an object from C. You define the body of the function later on in the C++ code as usual, if necessary inside a class etc, and you use the function in C like normal.