Hey all (and @ivanwfr),
The renewed interest by @dmonds made me curious enough to try again to make DLL calls, and I did actually get it to work this time. Here's how I did it:
1. Compile a simple C++ project to a DLL in Visual Studio, such as one consisting entirely of this .cpp source file:
extern "C" __declspec(dllexport) int __stdcall TestFunction()
{
return 42;
}
I created a few solutions, but some resulting DLLs were accepted as plugins and some were not, when plopped into the Plugins folder. When it's accepted, you'll see "Loaded plugin module <full path to DLL>" when opening the script editor. I'm not sure whether the DLL needs to be accepted this way, or whether it even needs to be in the Plugins folder at all. It does not seem to matter that compiling produces the message "Failed to map plugin module <full path to DLL>" since, as we'll see, we can accomplish the mapping step in code. It's very possible that TARGET will be finicky about the compiler options used to build the DLL, and we can work out which ones are important.
2. Create a simple, bare-bones TARGET script, such as this one:
include "target.tmh"
int fonctionne(){}
//program startup
int main()
{
if(Init(&EventHandle)) return 1; // declare the event handler, return on error
printf( "Hello world!\xa");
int lib = LoadLibrary("LibraryLoadTest.dll");
printf( "Library address: %d\xa", lib );
int funk = GetProcAddress(lib, "_TestFunction@0");
printf( "Library function address: %d\xa", funk );
int mapped = Map(&fonctionne, funk, MAP_IPTR_VPN); // returns object. mode:MAP_NORMAL=1, MAP_IPTR=2, MAP_IPTR_VPN=3, MAP_THISCALL=4
printf( "Mapped function address: %d\xa", mapped );
printf( "%d", fonctionne(), "\xa");
//add initialization code here
}
//event handler
int EventHandle(int type, alias o, int x)
{
DefaultMapping(&o, x);
//add event handling code here
}
You don't really need all the print statements, of course, and I'm sure you don't need to save the address returned by Map(). But if all goes well, you should see the number 42 in the editor's output window after the three large integer addresses.
The string "_TestFunction@0" can be discovered by running >dumpbin /EXPORTS <DLL file>. I tried unsuccessfully to compose the C++ in such a way that the exported function name is simply the same as in the source file, but there may be a way to do that.
I was so close before. I don't know why it took a three-year gap to hit on the right syntax. I certainly wish the jerks at ThrustMaster had made this procedure more clear. It wouldn't have taken much.