Ok, so this is a bit of continuation of that Euroscope question.
I’ve found a source in c++ for plugins, compiled it, made some changes and as a plugin it plays nicely. Upon opening c++ app, it calls c++ dll, initializes some class and plugin starts doing its job.
Now my CW app needs to talk to this dll or put simply - the plugin (dll) should act as a bridge, because direct comms between CW app and c++ app are not possible.
Approach? One simple way is exchanging data thru files, I guess. This would allow me not to be bothered by creating methods that are dll exported inside this dll and not to fiddle with exchanging data between (initialized) classes. I hope I’m using the right terms.
Any other option? I did succeed in creating a method in the dll, which my CW calls and it works, but I’m not skilled in c++ to make my methods inside dll push/pull data from the interface or instance (or whatever it is called/created) by c++ app.
Any ideas?
Thx
Bostjan
Hi Bostjan,
You can make a C wrapper in the C++ dll for any functions you need. In the C++ source add a define
and a wrapper function, e.g.
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int MyFunctionCall(char* szSourceString)
{
// do stuff
return 0;
}
In Clarion, run the libmaker.exe, select your C++ dll (now with C wrapper) and save the Clarion compatible library file. Include that in your Clarion project and in global map define as
module('example.dll')
MyFunctionCall(*cstring),LONG, RAW, DLL, C, name('MyFunctionCall')
end
If you need more complex return values than just a result code, you could add parameters such as
EXTERN_DLL_EXPORT int MyFunctionCall(char* szSourceString, unsigned char* outputByteArray, int* outputArraySize)
and use memcpy to copy local C/C++ data to those variables
localDataSize = outputArraySize
::memcpy(outputByteArray, localData, localDataSize);
Thank you!
It seems I misunderstood how this works. I thought that when cpp app loads up cpp plugin and i run my cw app, the latter “sucks up” to running dll and communicates.
However after some reading, cpp app loads the plugin, but my cw app does the same. So no attaching, it loads dll for itself. Now of course when cpp app is calling a method in dll which is a part of new class instance, my cw app knows nothing about that.
So when my cw app calls a method hoping to get some data, data isn’t there of course, my app is working in another instance of same class.
So how do both apps, which call the same dll see each other’s data values, if it’s even possible, I have no clue. I’m guessing both shoould be reading/writing to the same memory block.
So I managed to create some test methods in the cpp dll which I can call from cw app, which makes me happy knowing at least that works (the interaction). But I am playing with the idea that data exchange goes thru websockets. I would make plugin connect to my webserver app and we take it from there…
Ah, ok, so you want to access the data in a running instance of a plugin.
A web server and a client would work if you’re familiar with that.
Other options to consider:
- Memory-mapped files if both the plugin and your Clarion app are running in the same local session. There’s a good article with example code for this in Clarion Magazine archives
- SQL database
Message Queues (MSMQ) are probably overkill for this kind of usage and a pain to setup and maintain.
1 Like