SRL Archive - OSR Help

c++ plugin sample


bgtemp

2013-09-03 07:59:03

Hi!
I want to write c++ plugin for Simba, but I need example.
Anyone could show me sample code of working plugin in c++?

stata

2013-09-03 11:50:47

SMART is C++/Java, dunno if looking at that would help

Watcha making?

Hoodz

2013-09-03 11:55:48

What kind for plugin?

bgtemp

2013-09-03 12:29:19

Just normal .dll plugin.

SMART is far more then simple plugin, so I'm not sure if it is good example, it might have some additional stuff I don't need. Althought maybe it's the idea? I will check it.

Watcha making?


For now just simple "Hello Plugin" function, for future maybe something with WINAPI ;-)

tealc

2013-09-03 12:41:06

Here is some stuff on C plugins

http://villavu.com/forum/showthread.php?t=66021&highlight=
http://villavu.com/forum/showthread.php?t=64880&highlight=


also Brandon has a few c++ plugins here https://github.com/Brandon-T/GLX/tree/master/GLX

bgtemp

2013-09-03 13:24:04

Thanks ,I will look at them!

Lol ,every example looks quite different.

btw.

in Free Pascal there was something like:

procedure SetPluginMemManager(MemMgr : TMemoryManager); callconv export;
begin
if memisset then
exit;
GetMemoryManager(OldMemoryManager);
SetMemoryManager(MemMgr);
memisset := true;
end;

procedure OnDetach; callconv export;
begin
SetMemoryManager(OldMemoryManager);
end;

I don't see any equivalent in Dgby's example ,it's not necessary?

CynicRus

2013-09-03 14:09:53

Well, just look at the Benland's SMART sources, C++ plugin part is very easy for understanding.

https://github.com/BenLand100/SMART/blob/master/src/SmartRemote.cpp

bgtemp

2013-09-03 14:34:33

From: CynicRus
Well, just look at the Benland's SMART sources, C++ plugin part is very easy for understanding.

https://github.com/BenLand100/SMART/blob/master/src/SmartRemote.cpp


I've made my dll basing on SMART source. Simba loads it ,but can't see the function :/

I clearly did something wrong

dllmain.cpp
dllmain.h

Simba also says:

Plugin version:0 (although I have GetPluginABIVersion() )
The DLL doesn't set a memory menager.

CynicRus

2013-09-03 15:36:13

Simba in ABI2 uses cdedc function calls:) You trying to use stdcall model.

bgtemp

2013-09-03 16:08:41

Thanks, I'm one step further. I've replaced code in header with what I had commented before. dllmain.h updated

Simba now see my function, but cannot run it: Error: Could not call proc at line 5. It also still screams for memory menager.

Brandon

2013-09-03 20:14:05

Oh man.. This is might sound rough (I don't mean to be if it seems that way).. You might want to learn how to export functions from a dll before attempting to make any sort of plugin.


1. The declaration of dllmain isn't exactly right. The declaration for dllmain looks like:


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);

and if you decided to use the regular types instead of the microsoft typedefs, then it would look like:


bool __stdcall DllMain(HINSTANCE hinstDLL, unsigned int fdwReason, void* lpReserved);


Yes. You missed the calling convention and a DWORD is unsigned int. Not just int. Thought just int would still work, the calling convention you had was cdecl and that isn't correct.

2. You never exported the function "Add". Any program including Simba won't be able to get the function's address. This seems to be the problem you are currently having. Exporting it should fix it.

3. You might need C-Linkage for dllmain.

4. You don't exactly need a header for a basic plugin. You can have one but it isn't "required".

5. To specify C linkage for all functions, then you do:


extern "C"
{
void Add (int a, int b , int & res);
GetPluginABIVersion();
GetFunctionCount() ;
GetFunctionInfo(int index, void*& address, char*& def);
}


All in all, your code would then be:


#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#include <cstring>
#include <iostream>

#define NumExports 1
#if defined _WIN32 || defined _WIN64
HMODULE dllinst = NULL;
#endif

static char* exports[] =
{
(char*)"Add",(char*)"procedure Add(a, b :integer; var result : integer);"
};

extern "C" void __declspec(dllexport) Add (int a, int b , int & res)
{
res = a + b;

}

extern "C" int __declspec(dllexport) GetPluginABIVersion()
{
return 2;
}

extern "C" int __declspec(dllexport) GetFunctionCount()
{
return NumExports;
}

extern "C" int __declspec(dllexport) GetFunctionInfo(int index, void* &address, char* &def)
{
if (index < NumExports)
{
#if defined _WIN32 || defined _WIN64
address = (void*)GetProcAddress(dllinst, exports[index * 2]);
#else
address = dlsym(RTLD_DEFAULT, exports[index * 2]);
#endif
strcpy(def, exports[index * 2 + 1]);
return index;
}
return -1;
}

#if defined _WIN32 || defined _WIN64
extern "C" __declspec(dllexport) bool __stdcall DllMain(HINSTANCE instance, unsigned int reason, void* checks)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
{
dllinst = instance;
std::cout<<"Plugin Loaded..\n";
}
break;

case DLL_PROCESS_DETACH:
{
std::cout<<"Plugin UnLoaded..\n";
}
break;
}
return true;
}
#else
void OnProcessAttach() __attribute__((constructor))
{
std::cout<<"Plugin Loaded..\n";
}

void OnProcessDetach() __attribute__((destructor))
{
std::cout<<"Plugin UnLoaded..\n";
}
#endif

bgtemp

2013-09-04 13:21:14

Thanks, I compiled your code and it works! Not like I exactly know what I am doing , but it makes a little bit more sense now :)
I will base on this code in further work.


Oh man.. This is might sound rough (I don't mean to be if it seems that way).. You might want to learn how to export functions from a dll before attempting to make any sort of plugin.


Yes I definitively need to learn how to make dll! That's what I'm doing now :p To be honest it's my first dll in c++ and even first project in c/c++ for years. It's my learning project.